[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,6 +1,6 @@
<services>
<service name="tar_git">
- <param name="url">https://github.com/rinigus/pkg-libmicrohttpd</param>
+ <param name="url">https://github.com/sailfishos-chum/libmicrohttpd</param>
<param name="debian">N</param>
<param name="dumb">N</param>
</service>
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/doc/doxygen/libmicrohttpd.doxy
^
|
@@ -1,248 +0,0 @@
-# Doxyfile 1.5.5
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-DOXYFILE_ENCODING = UTF-8
-PROJECT_NAME = "GNU libmicrohttpd"
-PROJECT_NUMBER = 0.9.29
-OUTPUT_DIRECTORY = .
-CREATE_SUBDIRS = YES
-OUTPUT_LANGUAGE = English
-BRIEF_MEMBER_DESC = YES
-REPEAT_BRIEF = YES
-ABBREVIATE_BRIEF = "The $name class" \
- "The $name widget" \
- "The $name file" \
- is \
- provides \
- specifies \
- contains \
- represents \
- a \
- an \
- the
-ALWAYS_DETAILED_SEC = NO
-INLINE_INHERITED_MEMB = NO
-FULL_PATH_NAMES = YES
-STRIP_FROM_PATH = ../..
-STRIP_FROM_INC_PATH = ../../src/include \
- src/include
-SHORT_NAMES = NO
-JAVADOC_AUTOBRIEF = NO
-QT_AUTOBRIEF = NO
-MULTILINE_CPP_IS_BRIEF = NO
-INHERIT_DOCS = NO
-SEPARATE_MEMBER_PAGES = NO
-TAB_SIZE = 8
-ALIASES =
-OPTIMIZE_OUTPUT_FOR_C = YES
-OPTIMIZE_OUTPUT_JAVA = NO
-OPTIMIZE_FOR_FORTRAN = NO
-OPTIMIZE_OUTPUT_VHDL = NO
-BUILTIN_STL_SUPPORT = NO
-CPP_CLI_SUPPORT = NO
-SIP_SUPPORT = NO
-DISTRIBUTE_GROUP_DOC = NO
-SUBGROUPING = YES
-TYPEDEF_HIDES_STRUCT = NO
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-EXTRACT_ALL = YES
-EXTRACT_PRIVATE = NO
-EXTRACT_STATIC = YES
-EXTRACT_LOCAL_CLASSES = NO
-EXTRACT_LOCAL_METHODS = YES
-EXTRACT_ANON_NSPACES = NO
-HIDE_UNDOC_MEMBERS = NO
-HIDE_UNDOC_CLASSES = NO
-HIDE_FRIEND_COMPOUNDS = NO
-HIDE_IN_BODY_DOCS = NO
-INTERNAL_DOCS = NO
-CASE_SENSE_NAMES = YES
-HIDE_SCOPE_NAMES = NO
-SHOW_INCLUDE_FILES = YES
-INLINE_INFO = YES
-SORT_MEMBER_DOCS = YES
-SORT_BRIEF_DOCS = NO
-SORT_GROUP_NAMES = NO
-SORT_BY_SCOPE_NAME = NO
-GENERATE_TODOLIST = NO
-GENERATE_TESTLIST = NO
-GENERATE_BUGLIST = NO
-GENERATE_DEPRECATEDLIST= NO
-ENABLED_SECTIONS =
-MAX_INITIALIZER_LINES = 30
-SHOW_USED_FILES = YES
-FILE_VERSION_FILTER =
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-QUIET = NO
-WARNINGS = YES
-WARN_IF_UNDOCUMENTED = YES
-WARN_IF_DOC_ERROR = YES
-WARN_NO_PARAMDOC = NO
-WARN_FORMAT = "$file:$line: $text"
-WARN_LOGFILE =
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT = ../..
-INPUT_ENCODING = UTF-8
-FILE_PATTERNS = *.c \
- *.h
-RECURSIVE = YES
-EXCLUDE =
-EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS = */test_* */.svn/* */perf_* */tls_test_* */examples/* */testcurl/* */testzzuf/* */platform/* */symbian/* MHD_config.h
-EXCLUDE_SYMBOLS = MHD_DLOG
-EXAMPLE_PATH =
-EXAMPLE_PATTERNS = *
-EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
-FILTER_SOURCE_FILES = NO
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-SOURCE_BROWSER = YES
-INLINE_SOURCES = NO
-STRIP_CODE_COMMENTS = YES
-REFERENCED_BY_RELATION = YES
-REFERENCES_RELATION = YES
-REFERENCES_LINK_SOURCE = YES
-USE_HTAGS = NO
-VERBATIM_HEADERS = NO
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-ALPHABETICAL_INDEX = YES
-COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-GENERATE_HTML = YES
-HTML_OUTPUT = html
-HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
-GENERATE_HTMLHELP = NO
-GENERATE_DOCSET = NO
-DOCSET_FEEDNAME = "Doxygen generated docs"
-DOCSET_BUNDLE_ID = org.doxygen.Project
-HTML_DYNAMIC_SECTIONS = NO
-CHM_FILE =
-HHC_LOCATION =
-GENERATE_CHI = NO
-BINARY_TOC = NO
-TOC_EXPAND = NO
-DISABLE_INDEX = NO
-ENUM_VALUES_PER_LINE = 4
-GENERATE_TREEVIEW = YES
-TREEVIEW_WIDTH = 250
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-GENERATE_LATEX = NO
-LATEX_OUTPUT = latex
-LATEX_CMD_NAME = latex
-MAKEINDEX_CMD_NAME = makeindex
-COMPACT_LATEX = NO
-PAPER_TYPE = a4wide
-EXTRA_PACKAGES =
-LATEX_HEADER =
-PDF_HYPERLINKS = YES
-USE_PDFLATEX = YES
-LATEX_BATCHMODE = NO
-LATEX_HIDE_INDICES = NO
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-GENERATE_RTF = NO
-RTF_OUTPUT = rtf
-COMPACT_RTF = NO
-RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-GENERATE_MAN = NO
-MAN_OUTPUT = man
-MAN_EXTENSION = .3
-MAN_LINKS = NO
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-GENERATE_XML = NO
-XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
-XML_PROGRAMLISTING = YES
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-GENERATE_AUTOGEN_DEF = NO
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-GENERATE_PERLMOD = NO
-PERLMOD_LATEX = NO
-PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-ENABLE_PREPROCESSING = YES
-MACRO_EXPANSION = NO
-EXPAND_ONLY_PREDEF = NO
-SEARCH_INCLUDES = YES
-INCLUDE_PATH =
-INCLUDE_FILE_PATTERNS =
-PREDEFINED =
-EXPAND_AS_DEFINED =
-SKIP_FUNCTION_MACROS = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-TAGFILES =
-GENERATE_TAGFILE =
-ALLEXTERNALS = NO
-EXTERNAL_GROUPS = YES
-PERL_PATH = /usr/bin/perl
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-CLASS_DIAGRAMS = YES
-MSCGEN_PATH =
-HIDE_UNDOC_RELATIONS = YES
-HAVE_DOT = YES
-CLASS_GRAPH = NO
-COLLABORATION_GRAPH = NO
-GROUP_GRAPHS = NO
-UML_LOOK = NO
-TEMPLATE_RELATIONS = NO
-INCLUDE_GRAPH = YES
-INCLUDED_BY_GRAPH = YES
-CALL_GRAPH = YES
-CALLER_GRAPH = YES
-GRAPHICAL_HIERARCHY = NO
-DIRECTORY_GRAPH = YES
-DOT_IMAGE_FORMAT = png
-DOT_PATH =
-DOTFILE_DIRS =
-DOT_GRAPH_MAX_NODES = 25
-MAX_DOT_GRAPH_DEPTH = 2
-DOT_TRANSPARENT = YES
-DOT_MULTI_TARGETS = NO
-GENERATE_LEGEND = YES
-DOT_CLEANUP = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-SEARCHENGINE = YES
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/doc/performance_data.eps
^
|
@@ -1,8468 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: (ImageMagick)
-%%Title: (performance_data.eps)
-%%CreationDate: (2014-02-19T07:16:22+01:00)
-%%BoundingBox: -0 -0 640 480
-%%HiResBoundingBox: 0 0 640 480
-%%DocumentData: Clean7Bit
-%%LanguageLevel: 1
-%%Pages: 1
-%%EndComments
-
-%%BeginDefaults
-%%EndDefaults
-
-%%BeginProlog
-%
-% Display a color image. The image is displayed in color on
-% Postscript viewers or printers that support color, otherwise
-% it is displayed as grayscale.
-%
-/DirectClassPacket
-{
- %
- % Get a DirectClass packet.
- %
- % Parameters:
- % red.
- % green.
- % blue.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/DirectClassImage
-{
- %
- % Display a DirectClass image.
- %
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { DirectClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayDirectClassPacket } image
- } ifelse
-} bind def
-
-/GrayDirectClassPacket
-{
- %
- % Get a DirectClass packet; convert to grayscale.
- %
- % Parameters:
- % red
- % green
- % blue
- % length: number of pixels minus one of this color (optional).
- %
- currentfile color_packet readhexstring pop pop
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/GrayPseudoClassPacket
-{
- %
- % Get a PseudoClass packet; convert to grayscale.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- color_packet 0 get 0.299 mul
- color_packet 1 get 0.587 mul add
- color_packet 2 get 0.114 mul add
- cvi
- /gray_packet exch def
- compression 0 eq
- {
- /number_pixels 1 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add def
- } ifelse
- 0 1 number_pixels 1 sub
- {
- pixels exch gray_packet put
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassPacket
-{
- %
- % Get a PseudoClass packet.
- %
- % Parameters:
- % index: index into the colormap.
- % length: number of pixels minus one of this color (optional).
- %
- currentfile byte readhexstring pop 0 get
- /offset exch 3 mul def
- /color_packet colormap offset 3 getinterval def
- compression 0 eq
- {
- /number_pixels 3 def
- }
- {
- currentfile byte readhexstring pop 0 get
- /number_pixels exch 1 add 3 mul def
- } ifelse
- 0 3 number_pixels 1 sub
- {
- pixels exch color_packet putinterval
- } for
- pixels 0 number_pixels getinterval
-} bind def
-
-/PseudoClassImage
-{
- %
- % Display a PseudoClass image.
- %
- % Parameters:
- % class: 0-PseudoClass or 1-Grayscale.
- %
- currentfile buffer readline pop
- token pop /class exch def pop
- class 0 gt
- {
- currentfile buffer readline pop
- token pop /depth exch def pop
- /grays columns 8 add depth sub depth mul 8 idiv string def
- columns rows depth
- [
- columns 0 0
- rows neg 0 rows
- ]
- { currentfile grays readhexstring pop } image
- }
- {
- %
- % Parameters:
- % colors: number of colors in the colormap.
- % colormap: red, green, blue color packets.
- %
- currentfile buffer readline pop
- token pop /colors exch def pop
- /colors colors 3 mul def
- /colormap colors string def
- currentfile colormap readhexstring pop pop
- systemdict /colorimage known
- {
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { PseudoClassPacket } false 3 colorimage
- }
- {
- %
- % No colorimage operator; convert to grayscale.
- %
- columns rows 8
- [
- columns 0 0
- rows neg 0 rows
- ]
- { GrayPseudoClassPacket } image
- } ifelse
- } ifelse
-} bind def
-
-/DisplayImage
-{
- %
- % Display a DirectClass or PseudoClass image.
- %
- % Parameters:
- % x & y translation.
- % x & y scale.
- % label pointsize.
- % image label.
- % image columns & rows.
- % class: 0-DirectClass or 1-PseudoClass.
- % compression: 0-none or 1-RunlengthEncoded.
- % hex color packets.
- %
- gsave
- /buffer 512 string def
- /byte 1 string def
- /color_packet 3 string def
- /pixels 768 string def
-
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- x y translate
- currentfile buffer readline pop
- token pop /x exch def
- token pop /y exch def pop
- currentfile buffer readline pop
- token pop /pointsize exch def pop
- /Times-Roman findfont pointsize scalefont setfont
- x y scale
- currentfile buffer readline pop
- token pop /columns exch def
- token pop /rows exch def pop
- currentfile buffer readline pop
- token pop /class exch def pop
- currentfile buffer readline pop
- token pop /compression exch def pop
- class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
- grestore
-} bind def
-%%EndProlog
-%%Page: 1 1
-%%PageBoundingBox: 0 0 640 480
-userdict begin
-DisplayImage
-0 0
-640 480
-12
-640 480
-1
-0
-0
-102
-FFFFFF
-000000
-A0A0A0
-FF0000
-00C000
-0080FF
-C000FF
-00EEEE
-C04000
-C8C800
-4169E1
-FFC020
-008040
-C080FF
-306080
-8B0000
-408000
-FF80FF
-7FFFD4
-A52A2A
-FFFF00
-40E0D0
-000000
-1A1A1A
-333333
-4D4D4D
-666666
-7F7F7F
-999999
-B3B3B3
-C0C0C0
-CCCCCC
-E5E5E5
-FFFFFF
-F03232
-90EE90
-ADD8E6
-F055F0
-E0FFFF
-EEDD82
-FFB6C1
-AFEEEE
-FFD700
-00FF00
-006400
-00FF7F
-228B22
-2E8B57
-0000FF
-00008B
-191970
-000080
-0000CD
-87CEEB
-00FFFF
-FF00FF
-00CED1
-FF1493
-FF7F50
-F08080
-FF4500
-FA8072
-E9967A
-F0E68C
-BDB76B
-B8860B
-F5F5DC
-A08020
-FFA500
-EE82EE
-9400D3
-DDA0DD
-905040
-556B2F
-801400
-801414
-804014
-804080
-8060C0
-8060FF
-808000
-FF8040
-FFA040
-FFA060
-FFA070
-FFC0C0
-FFFF80
-FFFFC0
-CDB79E
-F0FFF0
-A0B6CD
-C1FFC1
-CDC0B0
-7CFF40
-A0FF20
-BEBEBE
-BFBFBF
-5F5F5F
-1F1F1F
-DFDFDF
-9F9F9F
-3F3F3F
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001010101010101010100010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000606101010000000000006361010161630000000000636101016163000000
-0063610101616300000000000000000000000000000000000000000000000000606101010000
-0000000000636101016163000000006361010161630000000063610101616300000000636101
-0161630000000063610101616300000000006361010161630000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000161000000000000006101
-0000010000000000000000010000000101010162651B63000000000100000000000000000000
-0000000000000001000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000010000000001010101010101010000
-0000000000000060650162616300000000010101010101000000006361010161630000000000
-00631B6562016261600000000000606162016265640000000000006361620101626160000001
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000621B6301000000000000621B63631B620000000000621B63631B6200000000621B63631B
-6200000000000000000000000000000000000000000000000000621B63010000000000000062
-1B63631B6200000000621B63631B6200000000621B63631B6200000000621B63631B62000000
-00621B63631B620000000000621B63631B620000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000162630000000000636501000001000000
-0000000000010000000100000063601B62640000000100000000000000000000000000000000
-0001000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000010000000000000000000000000000000000
-000000000000000000000000000000000001000000000000000000001B610000000000000000
-606264636364650000000001000000000000000000621B63631B620000000000606261606300
-631B621B00000000656463006360651B00000000646264630063646501000001000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000001
-00000000001B610000000061640000001B6100000000616400001B6100000000616400000000
-0000000000000000000000000000000000000000000000010000000000001B61000000006164
-00001B6100000000616400001B6100000000616400001B6100000000616400001B6100000000
-61640000001B6100000000616400000100000000000000000000000000000000000000000000
-000000000000000000000000000000011B610000000000616401000001000000000000000001
-0000000100000000000060626300000100000000000000000000000000000000000100000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000062600000000000000000656400000000
-64640000000100000000000000001B6100000000616400000064626000000000000000656100
-000000000000000063010000006362630000000000001B000001000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000001000000000001001B620162640000000001006162010000606501
-626400000000006065016264000000000000000000010000000000636101621B000000010061
-6201656300000000000000000000000000000000636162016264000000000001000000000065
-6000000000606500000065600000000060650000656000000000606500000000000000000000
-00000001001B6201626400000000000000010000000000006560000000006065000065600000
-0000606500006560000000006065000065600000000060650000656000000000606500000065
-60000000006065000001000000000000006362000000000000006260001B6201016560000000
-0000000000000000000163626300000063620001000001000000000000000001000000010000
-00000000001B6100000100000000001B62010165600000000000000100000000010061620165
-630000000060650162640000000001001B6201626400000000636162016264000001001B6201
-626400000001006162621B00006162016100000000636101621B000000000100616201000001
-0000000060626400010000000000000000000060650101656000000001001B62016264000000
-0000000000010000000000000000006065000000000000000000016300000000636500000001
-0000000000000000656000000000606500006362600060650101656001006260000000000000
-0000636200000061640000000000000000000001000000000000000001000001010101010101
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000001000000000001611B630060626400000001616400000063626400606260000000
-63626400606260000000000000000000000000000062640063611B0000016164636364626300
-0000000000000000000000000063621B63006061000000000001000000000062630000000063
-620000006263000000006362000062630000000063620000000000000000000000000001611B
-6300606264000000000000010000000000006263000000006362000062630000000063620000
-6263000000006362000062630000000063620000626300000000636200000062630000000063
-62000000000000000000000061640000000000646500611B6300636065000000000000000000
-0000000100611B0000001B1B0001000001000000000000000001000000010000000000000063
-6200000000000000611B63006360650000000000000000000000016164636364626300006362
-640060626000000001611B6300606264000063621B63006061000001611B6300606264000001
-61646363651B61646363656400000062640063611B0000000161640000000001000000606260
-0000000000000000000000006062646363646260000001611B63006062640000000000000001
-0000000000000000006564000000000000000000016300000000636200000001620162616300
-0000626300000000636200001B610060626463636401010064610000000000000060651B0000
-0062630000000000000000000001000000000000000001000000000000001B62000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000011B000000006065000000011B00000000611B0000006065000000611B00000060
-6500000000000000000000000000000000000063620000011B000000001B6100000000000000
-00000000000000611B0000000000000000000001000000000001000000000000010000000100
-0000000000010000010000000000000100000000000000000000000000011B00000000606500
-0000000000010000000000000100000000000001000001000000000000010000010000000000
-0001000001000000000000010000010000000000000100000001000000000000010000000000
-0000000000006062000000000062600001000000000000000000000000000000000000010063
-6200000062630001000001010101010101010101000000010000000000000000010000000000
-0000010000000000000000000000000000000000011B000000001B610000611B000000606500
-0000011B0000000060650000611B00000000000000011B000000006065000001640000006001
-640000006065000000000000006362000000011B000000000001000064656300000000000000
-00000000000061640000000064610000011B0000000060650000000000000001000000000000
-00006362000000000000000000006564000000006401000000656000631B6260000001000000
-0000000100006260006564000000006401006362000000000101010165000000000100000000
-0000000000000001010101010101010101000000000000646263000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000001
-6300000000636200000001630000000062630000006362000000626300000063620000000000
-0000000000000000001B62010101010000016300000000636200000000000000000000000000
-0062630000000000000000000001000000000001000000000000010000000100000000000001
-0000010000000000000100000000000000000000000000016300000000636200000000000001
-0000000000000100000000000001000001000000000000010000010000000000000100000100
-0000000000010000010000000000000100000001000000000000010000000000000000000000
-0065640000001B65000065616300000000000000000000000000000000010000656400646100
-0001000001000000000000000001000000010000000000000000010000000000000065616300
-0000000000000000000000000000016300000000636200006263000000636200000001630000
-0000636200006263000000000000000163000000006362000001630000000001630000000001
-0000001B62010101010000000163000000000001001B61000000000000000000000000000000
-62630000000063620000016300000000636200000000000000010000000000000000611B0000
-0000000000000000606264636364620100000000000000006465000001000000000000010000
-01000001630000000063010000010000000000006364621B0000000100000000000101010100
-0001000000000000000001000000000060626300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000001000000000000
-0100000001000000000001010101010101000000010101010101010000000000000000000000
-0000616560000000010000010000000000000100000000000000000101010100000100000000
-0000000000000001000000000062630000000063620000006263000000006362000062630000
-0000636200000000000000010101010000010000000000000100000000000001000000000000
-6263000000006362000062630000000063620000626300000000636200006263000000006362
-0000626300000000636200000062630000000063620000000000000000000000006062000000
-6264000063610162616000000000000000000000000000010000606200626000000100000100
-0000000000000001000000010000000000000063620000000000000063610162616000000000
-0000000000000000010000000000000100000101010101010100000001000000000000010000
-0100000000000000000100000000000001000001000000000001000000000001000061656000
-0000010000000100000000000001006263000000000000000000000000000000010000000000
-0001000001000000000000010000000000000001000000000000006362630000000001010101
-0000006065010165646200000000000000006301000062630000000063620000010000016300
-0000006301006362000000000000000060620000006263000000000000000100000100000000
-0000000001000000006062600000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000001000000000000010000000100
-0000000062630000000000000000626300000000000000000000000000000000000062630000
-0063010000016300000000636200000000000000000000000000006263000000000000000000
-0001000000000065600000000060650000006560000000006065000065600000000060650000
-0000000000000000000000010000000000000100000000000001000000000000656000000000
-6065000065600000000060650000656000000000606500006560000000006065000065600000
-00006065000000656000000000606500000000000000000000000000651B001B620000000000
-006364656100000000000000000000000001000000621B620000000100000100000000000000
-000100000001000000000000001B610000000000000000000063646561000000000000000000
-0000016300000000636200006263000000000000000001000000000000010000626300000000
-0000000100000000000001000001000000000001000000000001000062630000006301000000
-0100000000000001006462630000000000000000000000000000626300000000636200000100
-0000000000010000000000000001000000000000001B61000000000000000000000000000000
-0000606100000000000000006301000065600000000060650000626000656400000000640100
-646100000000000000000001000000611B000000000000000100000100000000000000000100
-0000636260000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000001000000000000010000000100000000006164
-0000000000000000616400000000000000000000000000000000000062630000001B01000001
-1B000000001B610000000000000000000000000000611B000000000000000000000100000000
-001B610000000061640000001B6100000000616400001B610000000061640000000000000000
-00000000000100000000000001000000000000010000000000001B6100000000616400001B61
-00000000616400001B6100000000616400001B6100000000616400001B610000000061640000
-001B610000000061640000000000000000000000000064016301640000000000000000630100
-0000000000000000000000010000006401640000000100000100000000000000000100000001
-00000000000063626300000000000000000000000063010000000000000000000000011B0000
-00001B6100006164000000000000000001000000000000010000611B00000000000000010000
-0000000001000001000000000001000000000001000062630000001B01000000010000000000
-0001000060626000000000000000000000000000616400000000646100000100000000000001
-0000000000000001000000000000006263000000000000000000000000000000000065600000
-000000000000646500001B6100000000616400001B6100606264636364620160626300000000
-0000000060620000006362630000000000000100000100000000000000000100006362640000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000001000000000000010000000100000000006362646300606500
-00006362646300606500000000000000000000000000616163631B6101000001616463636462
-63000000000000000000000000000063621B63006061000000000001000000000000621B6363
-1B620000000000621B63631B6200000000621B63631B62000000000000000000000000000001
-000000000000010000000000000100000000000000621B63631B6200000000621B63631B6200
-000000621B63631B6200000000621B63631B6200000000621B63631B620000000000621B6363
-1B620000000000000000000000000000006262620000000065646300631B6500000100000000
-000000000001000000000000000000010000010000000000000000010000000100000063601B
-6264000000000000000065646300631B65000000000000000000000001616463636462630000
-636264630060650000000100000000000001000063621B630060610000010000000000000100
-00010000000000010000000000010000616163631B6101000000010000000000000100000060
-6264000000000000000000000000606264636364626000000100000000000001000000000000
-000100000000000064650000000000000000000000000065600063616100000065646300631B
-6260000000621B63631B62000000636260006065010165600165630000006560630063646260
-0000000064621B630000631B010000010000000000000000010000621B000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000001000000000000010000000100000000000060650101656000000000606501
-0165600000000000000000000000000063616201610001000001006162016563000000000000
-0000000000000000000063616201656400000101010101010100000063610101616300000000
-0063610101616300000000636101016163000000000000000000000000000001000000000000
-0100000001010101010101000000006361010161630000000063610101616300000000636101
-0161630000000063610101616300000000636101016163000000000063610101616300000000
-00000000000000000000006401640000000060616201621B0000000100000000000000000001
-000000000000000000010000010000000000000000010000000101010162651B630000000000
-0000000060616201621B00000000000000000000000001006162016563000000006065010165
-6000000001000000000000010000006361620165640000010000000000000100000100000000
-000100000000000100006361620161000100000001000000000000010000000063621B000000
-0000000000000000006465010165600000000100000000000001000000000000000100000000
-0000656000000000000000000000000000646201626400000000606162016261630000000063
-6101016163000000006462600000000000000000000000006061620162616000000000000060
-6162010162616300000100000000000000000100000101010101010100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000060626160630063606165000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-1B65620101651B63000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000606101010000000000000000000000
-0000000000000000000000000000000000006361010161630000000000646201626400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000621B63010000000000000000000000000000000000
-000000000000000000000000621B63631B620000000061616300606500000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-00000000001B6100000000616400006065000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000006065016264000000000000000000010000000000000065
-6000000000606500006160000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000636264006062600000000000000000010000000000000062630000000063
-6200006264650101656000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000611B00000060650000000000000000010000000000000001000000000000010000016264
-6363646260000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000062630000
-0063620000000000000000010000000000000001000000000000010000016400000000646500
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000001010101010101000000
-0001010101010101010100000062630000000063620000626300000000630100000000000000
-0000000000000000000101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000062630000000000000000000000000001
-0000000000000065600000000060650000656300000000630100000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000010000000000000000000100000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000010000
-0000000000000100000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000010000000000000000000100000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0100000000000000000100000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000100000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000061640000000000000000000000000001000000000000
-001B610000000061640000646400000000646500000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000010000000000000000000100000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000010000000000000000
-0100000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000010000000000000000000100000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000010000000000
-0000000100000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000100000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000010000000000636264630060650000000000000000010000000000000000621B6363
-1B62000000006564636364626000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000101010101
-0101000000606501016560000000000000000001000000000000000063610101616300000000
-6361620165600000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010101000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000016263000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000101
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-6465000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001006564000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001006362630000000001000060
-6501016560000000000000000000606501626400000000010061620165630000000000606501
-0165600000010000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000100001B610000000001006062646363646260
-0000000000000063626400606260000000016164636364626300000060626463636462600001
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000656000000001006164000000006461000000000000
-00611B0000006065000000011B000000001B6100000061640000000064610001000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000636200000001006263000000006362000000000000006263000000
-6362000000016300000000636200000062630000000063620001000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000001B1B000001000100000000000001000000000000000101010101010100000001
-0000000000000100000001000000000000010001000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0065630001006263000000006362000000000000006263000000000000000001630000000063
-6200000062630000000063620001000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000006065000100
-61640000000064610000000000000061640000000000000000011B000000001B610000006164
-0000000064610001000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000010000000000001B640100606264636364
-6260000000000000006362646300606500000001616463636462630000006062646363646260
-0001000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000650100006465010165600000000000
-0000000060650101656000000001006162016563000000000064650101656000000100000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000101010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010101000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000000000004000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040000000400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400040000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000006200000000006301630000
-0000006201000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000040004000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000006164000000006401640000000064650100
-0000010000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004000000040000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000606100000000611B610000000061640000000001000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400000400000400000400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000006200000000626362000000636200010000010101010100000001001B
-6201626400000000000000000060650162640000000001006162016563000000006065010165
-6000000001000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000000040004000000000004000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000001B64000063650065630000646100010000000100000000000001611B630060626400
-0000000000006362640060626000000001616463636462630000606264636364626000000100
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000400000000000400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040004000000040000000400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000006065
-00006461001B6400006560000100000001000000000000011B00000000606500000000000000
-611B0000006065000000011B000000001B610000616400000000646100000100000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000400
-0000040000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400000000000400040000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000062630061640060
-6100636200000100000001000000000000016300000000636200000000000000626300000063
-6200000001630000000063620000626300000000636200000100000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000400000000
-0004000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000001B1B006263006362001B1B0000
-0100000001000000000000010000000000000100000000000000010101010101010000000100
-0000000000010000010000000000000100000100000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000400000004000000040004000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000063656362000000626362630000010000000100
-0000000000010000000000000100000000000000626300000000000000000163000000006362
-0000626300000000636200000100000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000004000400000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040000000000040004000000040000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000651B61000000611B65000000010000000100000000000001
-000000000000010000000000000061640000000000000000011B000000001B61000061640000
-0000646100000100000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000400000004000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000400000000000400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000064016400000064011B000000010000006264000000000001000000000000
-0100000000000000636264630060650000000161646363646263000060626463636462600000
-0100000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000040000000000040000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000630163000000630163000000010000006062010100000001000000000000010000000000
-0000006065010165600000000100616201656300000000646501016560000000010000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040000000000040000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010101000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000400000004000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001010100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040000
-0000000400000000000000000004000400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000400000004000000
-0000000000000000040000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004000400000000000000000000
-0004000400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000040000000000000000000000040000000400
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004000400000000000000000004000000000004000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400000004000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0000000000040000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000040000000000040000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400000004000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000606101
-0100000000000063610101616300000000636101016163000000006361010161630000000000
-6361010161630000000063610101616300000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000400000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000621B63010000000000
-00621B63631B6200000000621B63631B6200000000621B63631B620000000000621B63631B62
-00000000621B63631B6200000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000100000000001B6100000000
-616400001B6100000000616400001B610000000061640000001B6100000000616400001B6100
-0000006164000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000400
-0400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000656000000000606500006560
-0000000060650000656000000000606500000065600000000060650000656000000000606500
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040000000400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000626300000000636200006263000000006362
-0000626300000000636200000062630000000063620000626300000000636200000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004000000000004000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000010000000000000100000100000000000001000001000000
-0000000100000001000000000000010000010000000000000100000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000400000000000400000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000010000000000000100000100000000000001000001000000000000010000
-0001000000000000010000010000000000000100000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000000040000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000626300000000636200006263000000006362000062630000000063620000006263000000
-0063620000626300000000636200000000000000000000000000000000010101010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010101010100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000065600000
-0000606500006560000000006065000065600000000060650000006560000000006065000065
-6000000000606500000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000000000004
-0000000000000000000000000000000000000000000000000000000000000000000004040000
-0000040000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000100000000001B610000000061640000
-1B6100000000616400001B610000000061640000001B6100000000616400001B610000000061
-6400000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040000000400000000000000
-0000000000000000000000000000000000000000000000000000000004040400000400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000621B63631B6200000000621B63631B
-6200000000621B63631B620000000000621B63631B6200000000621B63631B62000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400040000000000000000000000000000
-0000000000000000000000000000000000000400000400000404040000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001010101010101000000636101016163000000006361010161630000000063
-6101016163000000000063610101616300000000636101016163000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000000000000000000000000000000000000000000
-0000000000000000000000000004040000040004040000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000400040000000000000000000000000000000000000000000004000000
-0000040000000000040004000400040000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040000000400000000000000000000000000000000000000000000040000000400000000
-0000000400040000000400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000101010000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000621B6300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000000000404000000
-0004000000000000000000000000000000000000000000000400040000000000000004000400
-0000000004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000063610161600000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040000000400000000000000000000
-0000000000000000000000000000000000000004000000000000000400000004000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000631B626564000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000400040000000000000000000000000000000000
-0000000000000000000000000400040000000000040000000000040000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000006465621B63000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004000000000000000000000000000000000000000000000000
-0000000000040000000400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000001B0101610000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400040000000000000000000000000000000000000000000000000000000400
-0000000004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000063
-1B626560001B6100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0000000400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000636162616300000063
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000400000000000400
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000006065621B63000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004000000000004000004000000
-0000040000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006564000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000040000000400000000040000000400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400040000000000000400040000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000006461000000000061640000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000000000000000004000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000626000
-0000000060650000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010101
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000400040000000000000400040000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001010100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000004000000
-0400000000040000000400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000626300000000006362000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000400000000000400000400
-0000000004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000611B00000000001B61000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-000000000000000000000063621B6300631B6263000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000006361620162616300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000400
-0000000004000000000000000000000000000000000004000000000004000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000000040000
-0000000000000000000000000000000000040000000400040000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000646562010101010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040004000000000000000000
-0000000000000000000000000400040004000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000064626063000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400000000000400000000000000000000
-0000000000000004000400000004000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000062600000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000040004000000040000000000000000000000000004000000
-0400040000000400000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000000040004000000000000000000000000000000040004000400040004
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0062630000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400000000000400000000000000000000000000000000000400040000000400000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000001B1B000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0004000000000000000004000000000004000004000000040004000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000611B6300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000400000004000000
-0000000000040000000400000400040004000000040000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000101010101010101010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040000000000040000000000000000
-0400040000040000000400000000000400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000400000400
-0000000004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040004000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000004000000040000000000000400000000000400
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000006065
-6201000065600000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000400000000000400000000000004000000040000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000646260630100006065
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040000000000040000040004000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000626000000100000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400000004000000000400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000100006301000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004000400000000040004000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000656400000100006465000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000004000000
-0004000000040004000000000004000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-000000000060621B630163646263000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400000000000400040000040000000000
-0400040000000400000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-6361620162616300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0101000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000400000000
-0004000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000000040000000400000000000000040000040004
-0400000400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000101010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000000040000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040004000000000004000000000000000400000404000004000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040004000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040400000000040000000000000000000004040404000400000400000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000400000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0404000004000000000000000000000004040004040000040000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030003030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040004000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000400000404040000
-0000000400000004000404000404040404000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000004000000040000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040000000004040000000000000400
-0000040400000404000404000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000030303
-0303030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000646200000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040000
-0000000400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400040000000000000004000404040004
-0004040004040004000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003030303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001010101010101
-0101626000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000040000000400000000000000040000000400000404000004
-0400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030303030303030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000000000004000000000004040400040004040000040004040000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030303030303030303030303030303030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000400000404000004040000000400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003030303030303030303030303030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000001B620101010101010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040004000404040404000400040004000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030303030303030303030303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000001B61630100631B61000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000060610101000000000000636101016163
-0000000063610101616300000000636101016163000000000063610101616300000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040000040400000004000000040000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0303030000000000030303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000006263000100000064610000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000621B6301000000000000621B63631B6200000000621B
-63631B6200000000621B63631B620000000000621B63631B6200000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040404
-0400000400000000000400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303030303030000000000
-0000000003030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0100000000620000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000100000000001B6100000000616400001B6100000000616400
-001B610000000061640000001B61000000006164000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040400000400000400
-0000040404000000040404000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000303030303030300000000000000000000000303
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000616400626000006362
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000065600000000060650000656000000000606500006560000000
-0060650000006560000000006065000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040004000004000004000400040404
-0004040404000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000303030303030300000000000000000000000003030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-00000000000000000000000000000000000000000000006362001B6563636161000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000062630000000063620000626300000000636200006263000000006362000000
-6263000000006362000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000000040000000004040004000404040404040000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000030303030303030000000000000000000000000000030303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000006162626163000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0001000000000000010000010000000000000100000100000000000001000000010000000000
-0001000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000400000000000400000000040400040404040404000004000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000303
-0303030303000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000100000000
-0000010000010000000000000100000100000000000001000000010000000000000100000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000040404040404040404000400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000303030303030300
-0000000000000000000000000000000303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000006263000000006362000062
-6300000000636200006263000000006362000000626300000000636200000000000000000000
-0000000000010101010100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000004040404040404040000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030000000000000000
-0000000000000000000003030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001010101010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000006560000000006065000065600000000060
-6500006560000000006065000000656000000000606500000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400000404040404040004040400040000000000000000000000000000000000000000000000
-0000000000000000000000000000000003030303030303000000000000000000000000000000
-0000000000030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000001B6100000000616400001B6100000000616400001B6100
-00000061640000001B6100000000616400000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000004040000
-0404000400040404000000000000000000000000000000000000000000000000000000000000
-0000000000000000000003030303030303000000000000000000000000000000000000000003
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000001010101010101010101010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000001000000000000621B63631B6200000000621B63631B6200000000621B63631B620000
-000000621B63631B620000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000404000000000404000400
-0400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000303030303030300000000000000000000000000000000000000000000030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010101010101
-0100000063610101616300000000636101016163000000006361010161630000000000636101
-0161630000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000400040004000400040000
-0004000000000000000000000000000000000000000000000000000000000000000003030303
-0303030300000000000000000000000000000000000000000000030303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000400040004000400040004000000
-0000000000000000000000000000000000000000000000000000000000000303030300000000
-0000000000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001010100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040004040404040004040404000000000000000000
-0000000000000000000000000000000000000000000003030303030303000000000000000000
-0000000000000000000000000000000303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010101000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000000040404040404040400000000000000000000000000000000
-0000000000000000000000000000000303030303030303000000000000000000000000000000
-0000000000000000000003030303030303000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000404040404040000040000000000000000000000000000000000000000
-0000000000000000000303030303030300000000000000000000000000000000000000000000
-0000000003030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400040004040404040004000000000000000000000000000000000000000000000000000000
-0000030303030303030000000000000000000000000000000000000000000000000000000003
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000400040404
-0404040400000000000000000000000000000000000000000000000000000000000003030303
-0303030000000000000000000000000000000000000000000000000000000000030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000064656201010101010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040004040404040404040400
-0400000000000000000000000000000000000000000000000000000303030303030303000000
-0000000000000000000000000000000000000000000000000000030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000006462606300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000404000400000404040404000000040000
-0000000000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000006260000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000040004000400040004000400000000000000
-0000000000000000000000000000000303030303030300000000000000000000000000000000
-0000000000000000000000000000000303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004000404040404000404040400000000000000000000000000
-0000000000000000000003030303000000000000000000000000000000000000000000000000
-0000000000000000000303030303030303000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000626300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004040404040404040000000000000000000000000000000000000000
-0000030303030303030000000000000000000000000000000000000000000000000000000000
-0000000003030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-00000000000000000000000000000000000000000000001B1B00000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000400040404040404000004000000000000000000000000000000000000000003030303
-0303030000000000000000000000000000000000000000000000000000000000000000000303
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000611B630000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000004000400
-0404040404000400000000000000000000000000000000000000000303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000003030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010101010101010101000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010101000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040004040404040404
-0000040000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000003030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000101
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004000404040404040404040404000004
-0000000000000000000000000000030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040400040000040404040400040404040000000000
-0000000000000000030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004040404040404040404000000000000000000000000
-0003030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000030303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000606562010000656000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000400000404040404040400000000000000000000000000000000030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000064626063010000606500000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040404040404040000040000000000000000000000030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000062600000010000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000404
-0004040404040404000400000000000000000000000003030300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000010000630100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000400040404040404
-0404040000000000000000000000030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0065640000010000646500000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004040404040404040404040004
-0000000000000003030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000003030303030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-00000000000000000000000000000000000000000000000000000000000000000060621B6301
-6364626300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000004000000000404040004000404040000000000
-0003030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000003030303030303000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000063616201626163000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040004040400040404000000000000030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000400040404040400000400000000000003030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0003030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040004000404040000040400000000030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003030303
-0303030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000006265600000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400040404040404040004000000000303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003030303030303030000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000064626564000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000404040004
-0404000400040403030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-1B62626400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040404000004040404000404
-0404030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000030303030303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000001B016264
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000404040404040404040403030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000030303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000636201000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040400040404040404040403030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000001B016264000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040004000404040404040304030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000646265640000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400040404040404030403040403030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0303000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000006462656000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004040404040404040304040404000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000030303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000062
-6160000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000404040404
-0004040404040404000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000063000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040400040304040404
-0400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040004030404040404030004000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000003030303030303000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000001010001010101010101010100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001010100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000400040404040404000404000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000101010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004040404040404040400040400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000303
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003040404030404040404040400000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000303030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030403030404040404040004000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000101010101
-0101010162640000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003030304
-0400040404000400000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000611B6300631B61636062
-6400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303030404030404040404
-0000040000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000003030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000006164000000000064610064650000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000003030400040404040404000404040400
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006263000000000063620063010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000003030303030304040400040404040404040400000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000163000000000063010000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003030303030303040004000404040404040000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003030303
-0303030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000006564000000000064650060650000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000303000000000400000404040404000004000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003030303030303030000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-000000000000000000000000000000000000000000000000000000000000000000000060621B
-6300631B62630065640000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0300000000040404040404000404000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000006361620162616300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000606101010000000000006361010161630000000063610101
-6163000000006361010161630000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000030303030303030000000404
-0404040404040400040000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000030303030303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000621B6301000000000000621B63631B6200000000621B63631B6200000000
-621B63631B620000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030000000000000404040404040404
-0404040400000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000100000000001B6100000000616400001B6100000000616400001B610000000061
-6400000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000003030303030303000000000004040000040404040404000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000656000000000606500006560000000006065000065600000000060650000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030300000000000000000004040404040400040004000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000062
-6300000000636200006263000000006362000062630000000063620000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030303000000000000000000000404000404040404000404000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0303000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000001000000000000
-0100000100000000000001000001000000000000010000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0300000000000000040400040404040400040404040000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000001000000000000010000010000
-0000000001000001000000000000010000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303030303000000000000
-0000000004040400040404040404040000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000062630000000063620000626300000000636200
-0062630000000063620000000000000000000000000000000001010101010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030000000000000000000000000404
-0004000404040404000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001010101010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000062000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000065600000000060650000656000000000606500006560000000
-0060650000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000303030303030303000000000000000000000000040004040404
-0400000404000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000003030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000061640000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000100000000001B6100000000616400001B6100000000616400001B61000000006164000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030300000000000000000000000004000404040404040404040404
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000611B63000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000621B63631B6200000000621B63631B6200000000621B63631B6200000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030303000000000000000000000000000000040404040404040404040400000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000303
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001010101010101010100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000101010101010100000063610101
-6163000000006361010161630000000063610101616300000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000003030303030303
-0000000000000000000000000000000404040404040404040404000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000003030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000303030000000000000000
-0000000000000000000004000004040404040404040400000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000101010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000030303000000000000000000000000000000
-0000000000000404040404040404040400000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010101000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000060616201626160000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000303030303030303000000000000000000000000000000000004
-0404040404040404040400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006062646300636462600000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003030303000000000000000000000000000000000000000000040404040404
-0404040004040000000000000000000000000000000000000000000000000000000000000000
-0000000000000000030303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000006564000000000064650000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000003
-0303030303030000000000000000000000000000000000000000000404040404040400040404
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000163000000000063010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000003030303030303
-0000000000000000000000000000000000000000040404040404040404040400000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000003
-0303000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000016300
-0000000063010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000303030303030300000000000000
-0000000000000000000000000000000404040404040404040004040400000000000000000000
-0000000000000000000000000000000000000000000000000000000000030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000656400000000006465
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000030303000000000000000000000000000000
-0000000000000000000004040400040404040404040000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000646264630063646260000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000303030303030300000000000000000000000000000000000000
-0000000004040004040404040404040404000000000000000000000000000000000000000000
-0000000000000000000000000000000000030303030303030300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000006061620162616000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000030303030303030000000000000000000000000000000000000000000000000000
-0404040404040404040400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0300030300000000000000000000000000000000000000000000000000000004040400040404
-0404040004000000000000000000000000000000000000000000000000000000000000000000
-0000000000000303030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030003030000
-0000000000000000000000000000000000000000000000000000040004040404040404040404
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000003030303000000000000000000
-0000000000000000000000000000000000000000000404040404040404040404000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0303030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000062600001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000030303030303030000000000000000000000000000
-0000000000000000000000000000000000040404040404040400040000000000000000000000
-0000000000000000000000000000000000000000000000000000000303030303030303000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000101010000000000000000000000000000000000
-0000000000000000000000000000000000000000000064620101010101010101010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000030303030303030000000000000000000000000000000000000000
-0000000000000000000004040404040404040404040400000000000000000000000000000000
-0000000000000000000000000000000000000000000003030303030303000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003030303030303030300000000000000000000000000000000000000000000000000
-0000000000000004040404040404040404000000000000000000000000000000000000000000
-0000000000000000000000000000000003030303030303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000003
-0003030300000000000000000000000000000000000000000000000000000000000000000000
-0404040404040404040404040400000000000000000000000000000000000000000000000000
-0000000000000000000003030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000003030303030000
-0000000000000000000000000000000000000000000000000000000000000000040404000404
-0404040404040400000000000000000000000000000000000000000000000000000000000000
-0000000000030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000400040404040404040404
-0400000000000000000000000000000000000000000000000000000000000000000000000003
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000003030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000004040404040404040404040000000000
-0000000000000000000000000000000000000000000000000000000000000003030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000404040404040404040404000000000000000000000000
-0000000000000000000000000000000000000000000000000000030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000040404040404040404040004000000000000000000000000000000
-0000000000000000000000000000000000000000030303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000040404040404040404040400040404000000000000000000000000000000000000
-0000000000000000000000000000030303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000006065000000610165000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400040404040404040404040400000000000000000000000000000000000000000000000000
-0000000000000000030303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000656000006465631B1B0000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000404040404
-0404040404040404000000000000000000000000000000000000000000000000000000000000
-0000000303030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000016300
-0061640063620000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000404040404040404
-0404040000000000000000000000000000000000000000000000000000000000000000030303
-0303030303000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000006263000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040404040404040404040404000000
-0000000000000000000000000000000000000000000000000000000000030303030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000626300630100006362000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000404040404040404040404040000000000000000
-0000000000000000000000000000000000000000000000000303030303030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-00000000000000000000000000000000001B1B00616100006461000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000030303
-0303000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040404040404040404040404040004000000000000000000000000
-0000000000000000000000000000000000000303030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000006101656300006560000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003030303030303000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040404040404040404040404000404000000000000000000000000000000000000
-0000000000000000000000000003030303030303000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000303030303030303000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0404040404040404040404040400000000000000000000000000000000000000000000000000
-0000000000000303030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000404040404
-0404040404040004000000000000000000000000000000000000000000000000000000000000
-0303030303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040000040404040404040404
-0404040000000000000000000000000000000000000000000000000000000000000303030303
-0303030303000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040404040404040404040404000000
-0000000000000000000000000000000000000000000000000000000003030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000646200000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000030000000003030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000004040404040404040400040000000000000000
-0000000000000000000000000000000000000000000003030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010101010101010101626000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030003000003030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000404040404040404040404040000000000000000000000000000
-0000000000000000000000000000000000030303030303030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000030303030303030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040004040404040404000400000000000000000000000000000000000000
-0000000000000000000003030303030303030303000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0060650000006101650000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001010100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000030303030303030303000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004000404040404040400040400000000000000000000000000000000000000000000000000
-0000000303030303030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010101000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000006560000064
-65631B1B00000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000004040404
-0404040404040400040000000000000000000000000000000000000000000000000000000000
-0303030303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000163000061640063620000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003030303
-0303030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000404040404040404
-0004000000000000000000000000000000000000000000000000000000000000030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000062630000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004040404040404040404040000
-0000000000000000000000000000000000000000000000000000030303030303030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006263006301000063620000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000300
-0000000000000000000000000000000000000000000303030303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404000404040404040404040400000000000000
-0000000000000000000000000000000000000000000303030303030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000001B1B006161000064610000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000300000000000000
-0000000000000000000000000000030003030303030303030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000400040404040404040404040400000000000000000000000000
-0000000000000000000000000000000003030303030303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000061016563000065600000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000300000000000000000300000000
-0000000000000000030303030303030003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004040404040404040404040000040000000000000000000000000000000000
-0000000000000000000303030303030303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000303030303030300000000000303000300000300000300
-0003030303030303000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0404040004040404040404040004000000000000000000000000000000000000000000000000
-0000000000030303030303030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003000000000300000300000300030303000300000300000303030303030303
-0000000003000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040404
-0404040404000404000000000000000000000000000000000000000000000000000000000303
-0303030303030303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0003000000000300000300000303030303030300000300000303030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040404040404040404
-0404000000000000000000000000000000000000000000000000000000000003030303030303
-0303030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000006065620100006560000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000300030000
-0303030303030303030303030303030303030303030303030300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040404040404040404040400000000
-0000000000000000000000000000000000000000000000000000030303030303030303030303
-0303000300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000646260630100006065000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000006061010100000000000063610101616300000000636101016163000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030303030303030300000003030303
-0303030303030300030303030303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040404040404040404040404000400000000000000
-0000000000000000000000000000000000000000000303030303030303030303030000030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000626000000100000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-621B6301000000000000621B63631B6200000000621B63631B62000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030000000000000000000000000000030003000300030300000003030003030003030300
-0300030303030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000400040404040404040404040000000000000000000000000000
-0000000000000000000000000000000003030303030303030303030300030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000100006301000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000001B6100000000616400001B610000000061640000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003000000
-0003000000000000000000030003030303030303030303030303030003000303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004000404040404040404040004000400000000000000000000000000000000
-0000000000000000000000030303030303030303030303030303030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000065640000010000
-6465000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000656000
-0000006065000065600000000060650000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000300000000000003000000000300000000
-0300030303030303030303030300000003030303030303000000000303000300000303030000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040404040404040404040400040000000000000000000000000000000000000000000000
-0000000000030303030303030303030303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000060621B63016364626300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000626300000000636200
-0062630000000063620000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000300000003030303030303000300000000030000030003
-0003000303030303030303000003000000000000000303000300000003000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040404
-0404040404040404040400000000000000000000000000000000000000000000000000000303
-0303030303030303030303030303030300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000636162016261630000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000010000000000000100000100000000
-0000010000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000300000003000003000303030303030300030000030003000300000003
-0300000003000003000000000303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040404040404040404
-0404040000000000000000000000000000000000000000000000000000000000030303030303
-0303030303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000010000000000000100000100000000000001000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0303030303030303000003000003000300030303030303030303030300000000030000000000
-0003000000000000000300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040404040404040404040400040400
-0000000000000000000000000000000000000000000000000000000303030303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000626300000000636200006263000000006362000000000000000000
-0000000000000001010101010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000030000
-0003000003000003000300000000030000030000000000000000030000000000000000000000
-0000000300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404040404040404040404040004000400000000
-0000000000000000000000000000000000000000000303030303030303030303030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000101010101000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001010101010101010100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000656000000000606500006560000000006065000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000030303030303030303
-0303030303000300030000030000000000000000000000000000000000000000000000030000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000404040404040404040404040400040000000000000000000000
-0000000000000000000000000000000003030303030303030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-631B610000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000100000000001B
-6100000000616400001B61000000006164000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030000000300000000000300000000
-0300030000030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040404040404040404040404000004000000000000000000000000000000
-0000000000000000000000000303030303030303030303030300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000001B1B0000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000621B63631B62
-00000000621B63631B6200000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000300000000000300000000030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0404040404040404040404040404000400000000000000000000000000000000000000000000
-0000000000000303030303030303030303030303030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000063620000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001010101010101000000636101016163000000006361
-0101616300000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000300000000000300030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000400040404
-0404040404040404040000000000000000000000000000000000000000000000000000000000
-0003030303030303030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040404040404040404
-0404040404000000000000000000000000000000000000000000000000000000030303030303
-0303030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000060620000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000101010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040004040404040404040404040404
-0404000000000000000000000000000000000000000000000000000303030303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001010100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000636062640000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003000000000000000000
-0000000000000000030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400000404040404040404040404040404040000000000
-0000000000000000000000000000000000000000000303030303030303030303030303000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010101
-0101016564000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000003000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000404040404040404040404040404000000000000000000000000
-0000000000000000000000000000000303030303030303030303030303030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040404040404040404040404040000040000000000000000000000000000
-0000000000000000000003030303030303030303030303000003000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000003030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004040404040404040404040404040004000000000000000000000000000000000000000000
-0000000000000303030303030303030303030303000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000040000040404
-0404040404040404040400000400000000000000000000000000000000000000000000000303
-0303030303030303030303030303000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010101010101010101010101000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040404040404040404
-0404040400040400000000000000000000000000000000000000000000000000000303030303
-0303030303030303030303000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000611B6300631B6100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040404040404040404040404040404
-0404000000000000000000000000000000000000000000000000000303030303030303030303
-0303000003000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000061
-6400000000001B61000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000004040404040404040404040404040000000004
-0000000000000000000000000000000000000303030303030303030303030303030303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000062630000000000
-6362000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004040404040404040404040404040400040404000000000000
-0000000000000000000000000000000300000003030303030303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001630000000000630100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404000404040404040404040404040404040400000000000000000000000000
-0000000000000000000300000003030303030303030303030303030300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000065640000000000646500000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0400040404040404040404040404040404040400000000000000000000000000000000000000
-0000000300000003030303030303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000063621B6300631B626300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001010100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000404040404
-0404040404040404040404040404000000000000000000000000000000000000000000000000
-0000000303030303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0101010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000636162016261630000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040404040404040404040404
-0404040404040404000400000000000000000000000000000000000000000000000003030303
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000404040404040404040404040404
-0404040000000400000000000000000000000000000000000000000003030303030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404040404040404040404040404040404040404
-0000000000000000000000000000000000000000000303030303030303030303030300000300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040004040404040404040404040404040404040400040000000000
-0000000000000000000000000000000000030303030303030303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000060656201000065600000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040404040404040404040404040404040004000004000000000000000000
-0000000000000000000000030303030303030303030303030300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000006462606301000060650000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040404040404040404040404040404040400000400000000000000000000000000000000
-0000000003030303030303030303030303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000006260000001000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040404
-0404040404040404040404040404040000000000000000000000000000000000000000000003
-0303030303030303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000001000063010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040404040404040404
-0404040404040404040404000000000000000000000000000000000000000003030303030303
-0303030303030303030300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000656400
-0001000064650000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040404040404040404040404040404
-0404040400000000000000000000000000000000000000000000030303030303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-000000000000000000000000000000000000000000000000000000000060621B630163646263
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040004040404040404040404040404040404040004
-0000000000040000000000000000000000000003030303030303030303030303030303030000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000006361620162616300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000004040404040404040404040404040404000400040000000400
-0000000000000000000000000000030303030303030303030303030303030303030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400040404040404040404040404040404040400000400040400000000000000
-0000000000000000030303030303030303030303030303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0000040404040404040404040404040404040404040004040004000000000000000000000000
-0000030303030303030303030303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000620000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000404040404
-0404040404040404040404040404040404040400000000000000000000000000000003030303
-0303030303030303030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000061
-6400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040004040404040404
-0404040404040404040400040400000000000000000000000000000000000003030303030303
-0303030303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000611B63000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000004040404040404040404040404040404
-0404040404000004000000000000000000000000000000030303030303030303030303030303
-0303030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001010101010101010100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400000404040404040404040404040404040404040004
-0000000000000000000000000000000003030303030303030303030303030303030303000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040404040404040404040404040404040404040404040400000000
-0000000000000000000000000003030303030303030303030303030303000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000004040000040400040404040404040404040404040404040400000000000000000000
-0000000000000003030303030303030303030303030303000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040400
-0000000404040404040404040404040404040404000400000000000000000000000000000000
-0003030303030303030303030303030303030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000404
-0004040404040404040404040400040000000000000000000000000000000000000003030303
-0303030303030303030303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000040400000404040404
-0404040404040404000404000000000004000000000000000000000303030303030303030303
-0303030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040404040404040404040404
-0404040400040000000400000000000000000000000303030303030303030303030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000003000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000004000004040404040404040404040404040000
-0400040000000000000000000000000000000303030303030303030303030300000300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000101010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400040404040404040404040404000000000400000000
-0000000000000000000000000303030303030303030303030303000300000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000003000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010101000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000630000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000303030303030300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004040404040404040404040404040400040004000000000000000000
-0000000000030303030303030303030303030303030303030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000003000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0060000001000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040404040404040404040404040400040404040000000004000000000303
-0303030303030303030303030303030303030300000000000000000000000000000000000000
-0000000000000000000000000000000000000003030303030303000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000101610163
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000300000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0404040404040404040404040404040400040404040000000400000000000000000303030303
-0303030303030300030303030000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000060610101626501630000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000404040404040404
-0404040404040404040004000400000400040000000000000000030303030303030303030303
-0303030303030303030000000000000000000000000000000000000000000000000000000000
-0000000000000000000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000163641B01016261000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000404040404040404040404040404
-0404000400040000000004000000000000000000000303030303030303030303030303030303
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0003030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000006164630100000001636461000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000004040404040404040404040404040404000400
-0404040400040004000000000000000000030303000303030303030003030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000006162010161646301000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004040404040404040404040404040404040004000404000000
-0400000000000000000000030303030303030303030303030303030303000000000000000000
-0000000000000000000000000000000000000000000000000000000000000300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000630165620101616463000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004040404040404040404040404040404040400040404040004000400000000
-0000000000000300000303030303030003030303030300030000000000030000000000000000
-0000000000000000000000000000000000000000000000000300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100006301616201000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004040404040404040404040404040404040004040000000400000000000000000000000000
-0303030303030303030303030303030303030000000000030000000000000000000000000000
-0000000000000000000000000000000303030303030300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000100
-0060000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000040004040404
-0404040404040404040404040404040404040004000400000000000000000000000000030303
-0303030303030303030303030000000300030000000000000000000000000000000000000000
-0000000000000000000000000300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000630000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000006061010100000000
-0000636101016163000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000404040404040404
-0404040404040400040404000000040000000000000000000000000303030303030303030303
-0303030303030303030303030303030000000000000000000000000000000000000000000000
-0000000000000300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000621B6301000000000000621B6363
-1B62000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400040404040404040404040404040404
-0404040404040004000400000000000000000000000000030303030303030303030303030303
-0000000300030000000000000000000000000000000000000000000000000000000000000000
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000001B61000000006164000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004040404040404040404040404040404040404040000
-0400000000000000000000000000000303030303030303030303030303030303030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000006560000000006065000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000404040404040404040404040404040404040404040004000400000000
-0000000000000000000000000303030303030303030303030303000000030003000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000006263000000006362000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000040404040404040404040404040404040400000404040400000000000000
-0000000303030303030303030303030303030303030000030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000100000000000001000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004040404040404040404040404040404040404040004040000000000000000000000000000
-0303030303030303030303030300030000030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000100000000000001000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000400040404
-0404040404040404040404040004040404000000000000000000000000000000030303030303
-0303030303030303030000030003030000000300000000000000000000000000000300000000
-0000000000000000030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000626300
-0000006362000000000000000000000000000000000101010101000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040004040404040404040404
-0404040004040400040400000000000000000000000000030303030303030303030303030303
-0303030303030003030000000300000000000000000000000000000300000000000000000000
-0000030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000101010101000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000656000000000606500
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004040404040400040004000004
-0004040404000000000000000000000000000000030303030303030303030303030303000003
-0003030000000300000000000000000000000000000300000000000000000000000003000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000100000000001B6100000000616400000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404040404040404000000040400040404000404
-0000000000000000000000030303030303030303030303030303030303030303030303030303
-0303030300000000000000000303030303030300000000000003030303030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000001000000000000621B63631B620000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040404040404040404040404040404040404040004040400040004
-0000000000000000030303030303030303040303030303040303030303000000030000000000
-0000000000000000000300000000000300000000000003000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010101010101010000006361010161630000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000004040404040404040404040404040404000404040004000400000000000000
-0000030003030303030303030403030304000303030303000000030000000000000000000000
-0000000300000000000300000000000003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0404040404040404040404040400040404040404000400040000000000000000000003000303
-0303030303030304030403000303030303000000030000000000000000000000000000030000
-0000000300000000000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010101000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000404040404
-0404040404040404040404040404040404000000040000000000000303030303030403030304
-0304040303040303030303030303000000000000000000030000000003030000030303030303
-0300000000000000000000000000000000000000000003000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001010100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000040004040404040404040404
-0404040404040404040400040004000000000000000003030303030304030303040403040400
-0303030303000300000000000000000000030000000003030000000000030000000000000000
-0000000000000000000000000000000003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000404040404040404040404040404040404
-0404040004000400000000000000000003030303030303040304040403040400030303030300
-0300000000000000000000030000000003030000000000030000000000000000000000000000
-0000000000000000000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000040404040404040404040404000404040404040404040004
-0004000000000003030303030303030303030404030304030304030303030303030303030000
-0000030303030303030303030303030000030000000000000000000000000000000000000000
-0003030303030303000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000404040404040404040404040404040404040404040404040004000000
-0000000003030000030303040304030403040300030303030300030300000000000000000003
-0000000003030003000000030000000000000300000000000000000000000000000000000300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000040004040404040404040404040404040404040404040400000400000000000000000303
-0000030304030303040303030400030303030300030300000000000000000003000000000303
-0003000000030000000000000300000000000000000000000000000000000300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000400040404
-0404040404040404040404040404040404040400040004000000000000000303000003040303
-0304030403030304030303030300030300000000000000000003000000000303000300000003
-0000000000000300000000000000000000000000000000000300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000030303030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000040404040404
-0404040404040404040404000004000000000000000000000003030303030303030303030303
-0303030303030303030303030300000000000000000000000303030303030303030303030303
-0303030300000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004040404040404040404040404
-0404040404040400040000000000000000000000000003030303030303030303030003030303
-0300030300000000000000000000000000000000000300000003000000000000030000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000004000404040404040404040404040404040404040404
-0404000404000004000000000004000003040303030304040303030304040303030003030300
-0300000300000300000000030003000303000003030000000000030000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000040404040404040404040404040404040404040404040404040400
-0000040000000400000003030403030304040403030404030303030003030300030000030000
-0300000000030003000303000003030000000000030000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000400040404040404040404040404040404040404040404000000000000040004
-0000000003030304030403030404040403030303030000030300030000030000030000000003
-0003000303000000030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000101010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0004000004040404040404040404040404040400040400000000000000000400000303030303
-0303040303030304040303030303030303030303030303030303030303030303030303030303
-0303030303030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010101000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000040004040404
-0404040404040404040404040404040404000000000000040004000000000303030403040303
-0404040403030303030000030300030000030000030000000003000300030300000003000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000004000004040404040404040404
-0404040404040404040004040000000004000000040000000303040303030404040303040403
-0303030000030300030000030000030000000003000300030300000003000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404000404040404040404040404040404040404
-0404040404040400000400000000000400040404040403040404040403040404030303030303
-0300030303030000030300030003030303030303030303030300030303000000000000000000
-0000000000000003000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000040004000404040404040404040404040404040404040404
-0000040004000000040000000404030404040404040304040403030303030303030003030303
-0000000300030000030303000303030303030300030303000000000000000000000000000000
-0003000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000400040004040404040404040404040404040404040404000400000004
-0004000000000304040404040404040404040303030303030303030003030303000000030003
-0000030303000303030303030300030303000000000000000000000000000000000300000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000004000400040400040404040404040404040404040000040000000000040000030303
-0303040403040403040404030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303000000000000000000000303030303030300000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040004
-0004040404040404040404040404040404040404000400000004000400000000030404040404
-0404040404040303030303030303030003030303000000030003000003030300030303030303
-0300030303000000000000000000000000000000000300000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004000400040404040404
-0404040404040404040404040404000004000400000004000000040403040404040404030404
-0403030303030303030003030303000000030003000003030300030303030303030003030300
-0000000000000000000000000000000300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000400040004040404040404040404040404
-0404040404040404040000040000000000040004040304040304040404040304040403030303
-0303030003030303000000030003000003030300030303030303030003030300000000000000
-0000000000000000000300000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000400040404040404040404040404040404040404040404
-0404040000040404000003040404040404040304040404040304040403040303030303030303
-0303000003030003030303030303030303030303030303030300000303000000000000000000
-0000000000000000030000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000004000404040404040404040404040404040404040404040404000000
-0404000004040000040404040404040404030404040304030303030303030303030300000303
-0003030303030303030303030303030303030300000303000000000000000000000000000000
-0000030000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000040004040404040404040404040404040404040404040000040004000404040400
-0000000404040404040404040404030403030303030303030303030300000303000303030303
-0303030303030303030303030300000303000000000000000000000000000000000003000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0400040404040404040404040404040404040404000000000400000304040303030303030404
-0404040304040403040303030303030303030303030303030303030303030303030303030303
-0303030303030303030303030303000000000000000000000003030303030303000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000004000404040404
-0404040404040404040404040404040000040004000404040400000000040404040404040404
-0404030403030303030303030303030300000303000303030303030303030303030303030303
-0300000303000000000000000000000000000000000003000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000400040404040404040404040404
-0404040404040404040404000000040400000404000004040404040404040403040404030403
-0303030303030303030300000303000303030303030303030303030303030303030000030300
-0000000000000000000000000000000003000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000040004040404040404040404040404040404040404
-0404040404000004040400000304040404040404030404040404030404040304030303030303
-0303030300000303000303030303030303030303030303030303030000030300000000000000
-0000000000000000000003000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000004040004040404040404
-0404040404040404040404040404040404040404040404040404040403040404040403040404
-0403030303030303030303030303030303030303030303030303030303030303030303030303
-0300030303000000030003000303030000000300000000000000000000030000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000040400040404000404040404040404
-0404040404040404040404040404040404000404040404040404040404040404030303030303
-0303030303030303030303030303030303030303030303030303030303030303030003030300
-0000030003000303030000000300000000000000000000030000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000404040404040404040404040404040404040404
-0404040404040404040400000004040404040404040404040403030303030303030303030303
-0303030303030303030303030303030303030303030303030303030003030300000003000300
-0303030000000300000000000000000000030000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010101
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004040004040400040404040404040404040004040404040404
-0404040000000003040404040403040404040303030303030303030303030303030303030303
-0303030303030303030303030303030303030303030303030303030303030303030303030303
-0303030300000000030303030303030000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001010100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404040404040404040404040404040404040404040404040404040404040000
-0004040404040404040404040403030303030303030303030303030303030303030303030303
-0303030303030303030303030303030003030300000003000300030303000000030000000000
-0000000000030000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0400040404000404040404040404040404040404040404040404040404040400040404040404
-0404040404040404030303030303030303030303030303030303030303030303030303030303
-0303030303030303030003030300000003000300030303000000030000000000000000000003
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000404000404040404
-0404040404040404040404040404040404040404040404040404040404040304040404040304
-0404040303030303030303030303030303030303030303030303030303030303030303030303
-0303030003030300000003000300030303000000030000000000000000000003000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000606101010000000000000000000000
-0000000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000621B63010000000000000000000000000000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000040400
-0404000404040404040404040404040404040404040404040404040404040404040404040404
-0404040404040404040303040303030303040303030303030303030303030303030303030303
-0303030303030303030303030303030303000303030000030303030303000000000303030300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000100000000000000000000000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000010000000000000000000100
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000000000000000
-0000000000000000000100000000000000000100000000000000000000000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000010404000404040404
-0401040404040404040404040404040404040404040404040404040404040404040404040404
-0404030304030403030304030303030303030303030303030303030303030303030303030303
-0303030303030303030303000303030000030303030303000000000303030300000000000000
-0000000000000000000000000100000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000000000000000000000000000000000100000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000100000000000000000000000000000000000000000000000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000000000000000000000000000010000000000000000000100000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000000000000000000000000000
-0000000100000000000000000100000000000000000000000000000000000000000000000000
-0000000100000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000010004040404040404040404040404
-0404040404040404040404040404040404040404040404040404040404040404040403040303
-0304030403030303030303030303030303030303030303030303030303030303030303030303
-0303030303000303030000030303030303000000000303030300000000000000000000000000
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000000000000000000000000000000000100000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010101010101010101
-0101010101010101010101010101010101010101010101010101010101010100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000004040404040404040404040404040404040404040404040404
-0404040404040404040404040404040404040404040403040303030403040303030303030303
-0303030303030303030303030303030303030303030303030303030303030300030303000003
-0303030303000000000303030300000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000404000404040404040004040404040404040404040404040404040404040404
-0404040404040404040404040404040403030403040303030403030303030303030303030303
-0303030303030303030303030303030303030303030303030300030303000003030303030300
-0000000303030300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000004
-0400040400040404040404040404040404040404040404040404040404040404040404040404
-0404040404040404040404030304030303030304030303030303030303030303030303030303
-0303030303030303030303030303030303030300030303000003030303030300000000030303
-0300000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000101010101
-0101000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000606101010000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000606101010000000000006361010161630000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000606101
-0100000000000063610101616300000000636101016163000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000060610101000000000000636101016163000000006361010161
-6300000000636101016163000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000060610101000000000000
-6361010161630000000063610101616300000000636101016163000000000063610101616300
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000006061010100000000000063610101616300000000636101016163000000006361
-0101616300000000006361010161630000000063610101616300000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000062
-1B63010000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000621B6301000000000000621B63631B620000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000621B63010000000000
-00621B63631B6200000000621B63631B62000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000621B6301000000000000621B63631B6200000000621B63631B620000000062
-1B63631B62000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000621B6301000000000000621B63631B62
-00000000621B63631B6200000000621B63631B620000000000621B63631B6200000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-621B6301000000000000621B63631B6200000000621B63631B6200000000621B63631B620000
-000000621B63631B6200000000621B63631B6200000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000100000000001B6100000000616400000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000100000000001B6100000000
-616400001B610000000061640000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000100000000001B6100000000616400001B6100000000616400001B61000000006164
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000100000000001B6100000000616400001B6100
-000000616400001B610000000061640000001B61000000006164000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000001B6100000000616400001B6100000000616400001B610000000061640000001B610000
-0000616400001B61000000006164000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000656000000000606500000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000000000656000000000606500006560
-0000000060650000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000065600000000060650000656000000000606500006560000000006065000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000065600000000060650000656000000000606500
-0065600000000060650000006560000000006065000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000656000
-0000006065000065600000000060650000656000000000606500000065600000000060650000
-6560000000006065000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000001000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000626300000000636200000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000000000626300000000636200006263000000006362
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000006263
-0000000063620000626300000000636200006263000000006362000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001000000000062630000000063620000626300000000636200006263000000
-0063620000006263000000006362000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010000000000626300000000636200
-0062630000000063620000626300000000636200000062630000000063620000626300000000
-6362000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000001000000000001
-0000000000000100000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000010000000000010000000000000100000100000000000001000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000100000000000001
-0000010000000000000100000100000000000001000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000001000000000000010000010000000000000100000100000000000001000000
-0100000000000001000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000010000000000010000000000000100000100000000
-0000010000010000000000000100000001000000000000010000010000000000000100000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000001000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000001000000000000
-0100000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000010000000000010000000000000100000100000000000001000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000100000000000001000001000000
-0000000100000100000000000001000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000100000000
-0001000000000000010000010000000000000100000100000000000001000000010000000000
-0001000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000010000000000010000000000000100000100000000000001000001
-0000000000000100000001000000000000010000010000000000000100000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000001000000000062630000000063620000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-0000626300000000636200006263000000006362000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000006263000000006362000062630000000063620000
-6263000000006362000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000100000000006263000000
-0063620000626300000000636200006263000000006362000000626300000000636200000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000010000000000626300000000636200006263000000006362000062630000000063
-6200000062630000000063620000626300000000636200000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000100
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000001000000000065600000000060650000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000001000000000065600000
-0000606500006560000000006065000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000006560000000006065000065600000000060650000656000000000
-6065000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000100000000006560000000006065000065
-6000000000606500006560000000006065000000656000000000606500000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000001
-0000000000656000000000606500006560000000006065000065600000000060650000006560
-0000000060650000656000000000606500000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000100000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000100000000001B610000000061640000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000100000000001B610000000061640000
-1B61000000006164000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0100000000001B6100000000616400001B6100000000616400001B6100000000616400000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000100000000001B6100000000616400001B610000000061
-6400001B610000000061640000001B6100000000616400000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000100000000001B
-6100000000616400001B6100000000616400001B610000000061640000001B61000000006164
-00001B6100000000616400000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0001000000000000621B63631B62000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001000000000000621B63631B6200000000621B63631B
-6200000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-00621B63631B6200000000621B63631B6200000000621B63631B620000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000001000000000000621B63631B6200000000621B63631B6200000000621B
-63631B620000000000621B63631B620000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000001000000000000621B63631B62
-00000000621B63631B6200000000621B63631B620000000000621B63631B6200000000621B63
-631B620000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000101010101010100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000101010101010100
-0000636101016163000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000001010101010101000000636101016163000000006361010161630000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000010101010101010000006361010161
-6300000000636101016163000000006361010161630000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0101010101010100000063610101616300000000636101016163000000006361010161630000
-0000006361010161630000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000001010101010101000000636101016163000000006361
-0101616300000000636101016163000000000063610101616300000000636101016163000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000100000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000063016100000000000000000000000000000000000001000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000100000000000000000000006101630000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000100000000000000000000000000010000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000061620000000000000000000000000000000000000001000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000010000
-0000000000000000000062610000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000100000000000000000000000000010000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-6301600000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000010000000000000000
-0000000060016300000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000100000000636101621B00000001010101010000006065016264000000000100
-1B62016264000000006361620162640065600000000000636200000000000000646500000000
-01006162621B0000616201610000000001000000006361620162640000010061620100006065
-01016560000000001B6201016560000000606501626400000000006361620162640000606501
-01656000000001001B620162640000000063650162610001000000001B620101656000000065
-6400000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-010000000062640063611B0000000100000000006362640060626000000001611B6300606264
-000063621B630060610064650000000000611B00000000000000656400000000016164636365
-1B6164636365640000000100000063621B630060610000016164000000606264636364626000
-00611B630063606500006362640060626000000063621B630060610060626463636462600000
-01611B6300606264000063626463631B6101000000611B630063606500000064610000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000010000000000
-0000006362000000010000000000611B0000006065000000011B0000000060650000611B0000
-0000000000626300000063016300000000000000626300000000016400000060016400000060
-6500000001000000611B00000000000000011B00000000616400000000646100000100000000
-00000000611B0000006065000000611B00000000000061640000000064610000011B00000000
-60650000611B000000001B010000000100000000000000000063620000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000001000000001B620101010100
-000001000000000062630000006362000000016300000000636200006263000000000000001B
-610000001B610000000000000000010000000000016300000000016300000000010000000100
-0000626300000000000000016300000000626300000000636200006561630000000000006263
-0000006362000000626300000000000062630000000063620000016300000000636200006263
-0000000063010000006561630000000000000000010000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000010000006165600000000100000001000000
-0000010101010101010000000100000000000001000001000000000000000063626300006260
-0000000000000000010000000000010000000000010000000000010000000100000001000000
-0000000000010000000000010000000000000100006361016261600000000101010101010100
-0000010000000000000001000000000000010000010000000000000100000100000000000001
-0000006361016261600000000000010000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000010000006263000000630100000001000000000062630000
-0000000000000100000000000001000062630000000000000000611B00646500000000000000
-0000626300000000010000000000010000000000010000000100000062630000000000000001
-0000000000626300000000636200000000006364656100006263000000000000000062630000
-0000000062630000000063620000010000000000000100006263000000006301000000000000
-6364656100000063620000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000100000062630000001B0100000001000000000061640000000000000000
-01000000000000010000611B0000000000000000636200656400000000000000000061640000
-00000100000000000100000000000100000001000000611B0000000000000001000000000061
-64000000006461000000000000006301000061640000000000000000611B0000000000006164
-000000006461000001000000000000010000611B000000001B01000000000000000063010000
-0064610000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-000001000000616163631B610100000062640000000063626463006065000000010000000000
-0001000063621B6300606100000000651B620000000000000000000064650000000001000000
-0000010000000000010000000100000063621B63006061000001000000000060626463636462
-60000065646300631B6500006362646300606500000063621B63006061006062646363646260
-000001000000000000010000636264636364610100000065646300631B650000006564000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000001000000
-6361620161000100000060620101000000606501016560000000010000000000000100000063
-61620165640000000060011B0000000000000000000063016000000001000000000001000000
-0000010000000100000000636162016564000001000000000000646501016560000000606162
-01621B0000000060650101656000000000636162016564000064650101656000000001000000
-000000010000006365016261000100000060616201621B000000600163000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000001630000000000000000000000616200000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000626100000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000000000000000631B6100
-0000000000000000000000630161000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000061016300000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000101610000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000000000000000
-0000000000000000
-
-end
-%%PageTrailer
-%%Trailer
-%%EOF
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/po/configure.ac.in
^
|
@@ -1,17 +0,0 @@
-# This configure.ac.in is in the public domain
-
-# Use versions from parent configure
-AC_INIT([@PACKAGE_NAME@], [@PACKAGE_VERSION@], [@PACKAGE_BUGREPORT@])
-
-AC_CONFIG_SRCDIR([Makevars])
-AC_CONFIG_MACRO_DIR([../m4])
-AC_CONFIG_AUX_DIR([..])
-AM_INIT_AUTOMAKE([silent-rules])
-
-AM_GNU_GETTEXT([external])
-
-# gettext expect that 'po' files will stay in subdirectory.
-# Form './Makefile.in' is accepted by gettext as subdirectory but caused some
-# troubles with in-place build (with relative path to source files). To workaround
-# this, some hack are used in Makefile.
-AC_OUTPUT([./Makefile.in])
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/src/testcurl/https/cert.pem
^
|
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0
-MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC
-AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X
-fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud
-3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/
-GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv
-rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh
-siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O
-BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2
-RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN
-8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/
-0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe
-JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3
-OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV
-RhZvQx74NQnS6g==
------END CERTIFICATE-----
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/src/testcurl/https/key.pem
^
|
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf
-qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I
-niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+
-faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx
-7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ
-vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj
-lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R
-EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l
-/5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx
-u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/
-dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo
-32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc
-+JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd
-RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6
-OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob
-XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF
-hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae
-SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b
-AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH
-6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3
-QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG
-7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj
-P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9
-/Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC
-eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx
------END RSA PRIVATE KEY-----
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/src/testcurl/test_options.c
^
|
@@ -1,125 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2007 Christian Grothoff
-
- libmicrohttpd is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- libmicrohttpd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with libmicrohttpd; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
- */
-
-/**
- * @file mhds_get_test.c
- * @brief Testcase for libmicrohttpd HTTPS GET operations
- * @author Sagie Amir
- */
-
-#include "platform.h"
-#include "microhttpd.h"
-#include "mhd_sockets.h"
-
-#define MHD_E_MEM "Error: memory error\n"
-#define MHD_E_SERVER_INIT "Error: failed to start server\n"
-
-const int DEBUG_GNUTLS_LOG_LEVEL = 0;
-const char *test_file_name = "https_test_file";
-const char test_file_data[] = "Hello World\n";
-
-static int
-ahc_echo (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data, size_t *upload_data_size,
- void **unused)
-{
- return 0;
-}
-
-int
-test_wrap (char *test_name, int (*test) (void))
-{
- int ret;
-
- fprintf (stdout, "running test: %s ", test_name);
- ret = test ();
- if (ret == 0)
- {
- fprintf (stdout, "[pass]\n");
- }
- else
- {
- fprintf (stdout, "[fail]\n");
- }
- return ret;
-}
-
-
-/**
- * Test daemon initialization with the MHD_OPTION_SOCK_ADDR option
- */
-static int
-test_ip_addr_option ()
-{
- struct MHD_Daemon *d;
- struct sockaddr_in daemon_ip_addr;
-#if HAVE_INET6
- struct sockaddr_in6 daemon_ip_addr6;
-#endif
-
- memset (&daemon_ip_addr, 0, sizeof (struct sockaddr_in));
- daemon_ip_addr.sin_family = AF_INET;
- daemon_ip_addr.sin_port = htons (4233);
- daemon_ip_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-#if HAVE_INET6
- memset (&daemon_ip_addr6, 0, sizeof (struct sockaddr_in6));
- daemon_ip_addr6.sin6_family = AF_INET6;
- daemon_ip_addr6.sin6_port = htons (4233);
- daemon_ip_addr6.sin6_addr = in6addr_loopback;
-#endif
-
- d = MHD_start_daemon (MHD_USE_ERROR_LOG, 4233,
- NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
- &daemon_ip_addr, MHD_OPTION_END);
-
- if (d == 0)
- return -1;
-
- MHD_stop_daemon (d);
-
-#if HAVE_INET6
- d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_IPv6, 4233,
- NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
- &daemon_ip_addr6, MHD_OPTION_END);
-
- if (d == 0)
- return -1;
-
- MHD_stop_daemon (d);
-#endif
-
- return 0;
-}
-
-/* setup a temporary transfer test file */
-int
-main (int argc, char *const *argv)
-{
- unsigned int errorCount = 0;
-
- errorCount += test_wrap ("ip addr option", &test_ip_addr_option);
-
- return errorCount != 0;
-}
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/src/testcurl/test_start_stop.c
^
|
@@ -1,129 +0,0 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2011 Christian Grothoff
-
- libmicrohttpd is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- libmicrohttpd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with libmicrohttpd; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file test_start_stop.c
- * @brief test for #1901 (start+stop)
- * @author Christian Grothoff
- */
-#include "MHD_config.h"
-#include "platform.h"
-#include <curl/curl.h>
-#include <microhttpd.h>
-
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
-#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
-#endif
-
-
-static int
-ahc_echo (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data, size_t *upload_data_size,
- void **unused)
-{
- return MHD_NO;
-}
-
-
-static int
-testInternalGet (int poll_flag)
-{
- struct MHD_Daemon *d;
-
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
- if (d == NULL)
- return 1;
- MHD_stop_daemon (d);
- return 0;
-}
-
-static int
-testMultithreadedGet (int poll_flag)
-{
- struct MHD_Daemon *d;
-
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
- if (d == NULL)
- return 2;
- MHD_stop_daemon (d);
- return 0;
-}
-
-static int
-testMultithreadedPoolGet (int poll_flag)
-{
- struct MHD_Daemon *d;
-
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
- if (d == NULL)
- return 4;
- MHD_stop_daemon (d);
- return 0;
-}
-
-static int
-testExternalGet ()
-{
- struct MHD_Daemon *d;
-
- d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
- if (d == NULL)
- return 8;
- MHD_stop_daemon (d);
- return 0;
-}
-
-
-int
-main (int argc, char *const *argv)
-{
- unsigned int errorCount = 0;
-
- errorCount += testInternalGet (0);
- errorCount += testMultithreadedGet (0);
- errorCount += testMultithreadedPoolGet (0);
- errorCount += testExternalGet ();
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
- {
- errorCount += testInternalGet(MHD_USE_POLL);
- errorCount += testMultithreadedGet(MHD_USE_POLL);
- errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
- }
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
- {
- errorCount += testInternalGet(MHD_USE_EPOLL);
- errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL);
- }
- if (errorCount != 0)
- fprintf (stderr, "Error (code: %u)\n", errorCount);
- return errorCount != 0; /* 0 == pass */
-}
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/symbian/MHD_config.h
^
|
@@ -1,261 +0,0 @@
-/* MHD_config.h. Generated from MHD_config.h.in by configure. */
-/* MHD_config.h.in. Generated from configure.ac by autoheader. */
-
-#define _GNU_SOURCE 1
-
-/* This is a Cygwin system */
-#define CYGWIN 1
-
-/* This is a FreeBSD system */
-/* #undef FREEBSD */
-
-/* GNULIB_GC_RANDOM */
-#define GNULIB_GC_RANDOM 1
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the declaration of `TCP_CORK', and to 0 if you
- don't. */
-#define HAVE_DECL_TCP_CORK 0
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#define HAVE_FSEEKO 1
-
-/* Provides IPv6 headers */
-#undef HAVE_INET6
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have a functional curl library. */
-#define HAVE_LIBCURL 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define to 1 if you have the <math.h> header file. */
-#define HAVE_MATH_H 1
-
-/* Define to 1 if you have the `memmem' function. */
-#define HAVE_MEMMEM 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Include error messages */
-#define HAVE_MESSAGES 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#define HAVE_NETINET_TCP_H 1
-
-/* Define to 1 if you have the <pthread.h> header file. */
-#define HAVE_PTHREAD_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/mman.h> header file. */
-#define HAVE_SYS_MMAN_H 1
-
-/* Define to 1 if you have the <sys/msg.h> header file. */
-#define HAVE_SYS_MSG_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* disable HTTPS support */
-#define HTTPS_SUPPORT 0
-
-/* Defined if libcurl supports AsynchDNS */
-/* #undef LIBCURL_FEATURE_ASYNCHDNS */
-
-/* Defined if libcurl supports IDN */
-/* #undef LIBCURL_FEATURE_IDN */
-
-/* Defined if libcurl supports IPv6 */
-/* #undef LIBCURL_FEATURE_IPV6 */
-
-/* Defined if libcurl supports KRB4 */
-/* #undef LIBCURL_FEATURE_KRB4 */
-
-/* Defined if libcurl supports libz */
-#define LIBCURL_FEATURE_LIBZ 1
-
-/* Defined if libcurl supports NTLM */
-#define LIBCURL_FEATURE_NTLM 1
-
-/* Defined if libcurl supports SSL */
-#define LIBCURL_FEATURE_SSL 1
-
-/* Defined if libcurl supports SSPI */
-/* #undef LIBCURL_FEATURE_SSPI */
-
-/* Defined if libcurl supports DICT */
-#define LIBCURL_PROTOCOL_DICT 1
-
-/* Defined if libcurl supports FILE */
-#define LIBCURL_PROTOCOL_FILE 1
-
-/* Defined if libcurl supports FTP */
-#define LIBCURL_PROTOCOL_FTP 1
-
-/* Defined if libcurl supports FTPS */
-#define LIBCURL_PROTOCOL_FTPS 1
-
-/* Defined if libcurl supports HTTP */
-#define LIBCURL_PROTOCOL_HTTP 1
-
-/* Defined if libcurl supports HTTPS */
-#define LIBCURL_PROTOCOL_HTTPS 1
-
-/* Defined if libcurl supports LDAP */
-#define LIBCURL_PROTOCOL_LDAP 1
-
-/* Defined if libcurl supports TELNET */
-#define LIBCURL_PROTOCOL_TELNET 1
-
-/* Defined if libcurl supports TFTP */
-#define LIBCURL_PROTOCOL_TFTP 1
-
-/* This is a Linux system */
-/* #undef LINUX */
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* Compile client side code. This will enable running some test cases. */
-#define MHD_DEBUG_TLS 0
-
-/* gcrypt lib version */
-#define MHD_GCRYPT_VERSION "1:1.2.4"
-
-/* gnuTLS lib version - used in conjunction with cURL */
-#define MHD_REQ_CURL_GNUTLS_VERSION "2.2.3"
-
-/* required cURL SSL version to run tests */
-#define MHD_REQ_CURL_OPENSSL_VERSION "0.9.8"
-
-/* required cURL version to run tests */
-#define MHD_REQ_CURL_VERSION "7.16.4"
-
-/* This is a MinGW system */
-/* #undef MINGW */
-
-/* This is a NetBSD system */
-/* #undef NETBSD */
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* This is an OpenBSD system */
-/* #undef OPENBSD */
-
-/* This is a OS/390 system */
-/* #undef OS390 */
-
-/* This is an OS X system */
-/* #undef OSX */
-
-/* Some strange OS */
-/* #undef OTHEROS */
-
-/* Name of package */
-#define PACKAGE "libmicrohttpd"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "libmicrohttpd@gnu.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libmicrohttpd"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libmicrohttpd 0.4.2"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libmicrohttpd"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.4.2"
-
-/* This is a Solaris system */
-/* #undef SOLARIS */
-
-/* This is a BSD system */
-/* #undef SOMEBSD */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.9.0"
-
-/* This is a Windows system */
-/* #undef WINDOWS */
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-/* #undef _LARGEFILE_SOURCE */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Need with solaris or errno doesnt work */
-/* #undef _REENTRANT */
-
-/* Define curl_free() as free() if our version of curl lacks curl_free. */
-/* #undef curl_free */
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/symbian/README.txt
^
|
@@ -1,13 +0,0 @@
-Note: plibc was removed from MHD after this was written, so most likely
-the following won't work anymore right now. As usual, patches are welcome...
-
-
-This directory contains a MHD_config.h that allows compilation on Symbian OS 9
-with OpenC 1.6 (possibly earlier and later versions too) and plibc. It also
-contains a Scons-for-Symbian (http://code.google.com/p/scons-for-symbian/)
-SConstruct file that compiler the code into a static library, as an example
-of how to use this. It assumes that plibc is checked out into <libmicrohttpd
-directory>/../plibc.
-
-Since Symbian lacks POSIX signals you need to run this in 'external select
-loop' mode.
|
[-]
[+]
|
Deleted |
_service:tar_git:libmicrohttpd-0.9.55.tar.gz/libmicrohttpd/symbian/SConstruct
^
|
@@ -1,39 +0,0 @@
-from scons_symbian import *
-
-def MicroHttpd():
- target = "microhttpd"
- targettype = "lib"
- libraries = [ "euser", "libc", "libstdcpp" ]
-
- uid3 = 0
-
- sources = Glob("../src/daemon/*c", strings = True)
- sources += Glob("../../plibc/src/*search.c", strings = True)
- sources = [ s for s in sources if s.find("test") < 0 ]
- sources = [ s for s in sources if s.find("https") < 0 ]
-
- includes = ['.',
- '../src/include',
- '../../libc/src/include',
- ]
- sysincludes = [ EPOC32_INCLUDE,
- join(EPOC32_INCLUDE, 'stdapis'),
- join(EPOC32_INCLUDE, 'stdapis', 'stlport'),
- join(EPOC32_INCLUDE, 'libc'),
- ]
- defines = [
- "_STLP_NO_WCHAR_T",
- ]
-
- return SymbianProgram( target, targettype,
- sources = sources,
- includes = includes,
- sysincludes = sysincludes,
- libraries = libraries,
- defines = defines,
- epocstacksize = 8192,
- epocheapsize = (0x1000,0x100000),
- uid3 = uid3,
- )
-
-microhttpd = MicroHttpd()
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/.dir-locals.el
^
|
@@ -0,0 +1,16 @@
+;; Per-directory local variables for GNU Emacs 23 and later.
+
+((nil
+ . ((fill-column . 78)
+ (tab-width . 4)
+ (indent-tabs-mode . nil)
+ (show-trailing-whitespace . t)
+ (c-basic-offset . 2)
+ (ispell-check-comments . exclusive)
+ (ispell-local-dictionary . "british")
+ (safe-local-variable-values
+ '((c-default-style . "gnu")
+ (sentence-end-double-space . f)
+ (eval add-hook 'prog-mode-hook #'flyspell-prog-mode)
+ (flyspell-issue-message-flag . f) ; avoid messages for every word
+ )))))
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/.gitattributes
^
|
@@ -0,0 +1,5 @@
+*.m4 eol=lf
+*.sh eol=lf
+configure.ac eol=lf
+makefile.am eol=lf
+.gitattributes eol=lf
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/.gitignore
^
|
@@ -2,6 +2,7 @@
Makefile
.deps
.libs
+config.rpath
/test-driver
/INSTALL
/libmicrohttpd.pc
@@ -13,6 +14,16 @@
/config.log
/app.info
/debug
+/build-aux/texinfo.tex
+/build-aux/config.sub
+/build-aux/depcomp
+/build-aux/install-sh
+/build-aux/ltmain.sh
+/build-aux/mdate-sh
+/build-aux/test-driver
+/build-aux/config.guess
+/build-aux/compile
+/build-aux/missing
/exclude
/autom4te.cache
/scripts
@@ -22,6 +33,7 @@
/.project
/config.guess
/.cproject
+/.tgitconfig
/configure
/libtool
/install-sh
@@ -37,15 +49,16 @@
/depcomp
/.autotools
/.vscode
+/.settings
+/.vs
po/configure.acT
po/Makevars.template
po/POTFILES
-src/examples/timeout
-src/microhttpd/test_daemon.trs
-src/microhttpd/test_shutdown_poll
-src/microhttpd/test_shutdown_select
-src/microhttpd/test_str_compare
-src/microhttpd/test_str_to_value
-src/microhttpd/test_upgrade
-src/microhttpd/test_upgrade_ssl
-src/testcurl/test_delete
+po/configargs.stamp
+**~
+\#*\#
+doc/libmicrohttpd.log
+src/examples/suspend_resume_epoll
+uncrustify.cfg
+**.dvi
+**.t2d
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/.gitlab-ci.yml
^
|
@@ -0,0 +1,124 @@
+# we utilize the images generated by the build-images project, to
+# speed up CI runs. We also use ccache and store config.cache
+# to speed up compilation. We include a version number in cache
+# name to allow expiration of old caches.
+
+cache:
+ key: "$CI_JOB_NAME-ver1"
+ paths:
+ - cache/
+
+before_script:
+ # CCache Config
+ - mkdir -p cache
+ - export CCACHE_BASEDIR=${PWD}
+ - export CCACHE_DIR=${PWD}/cache
+ - export CC="ccache gcc"
+
+after_script:
+ # somehow after_script looses environment
+ - export CCACHE_BASEDIR=${PWD}
+ - export CCACHE_DIR=${PWD}/cache
+ - ccache -s
+
+variables:
+ BUILD_IMAGES_PROJECT: libmicrohttpd/build-images
+ DEBIAN_BUILD: buildenv-debian-stretch
+ MINGW_BUILD: buildenv-debian-mingw
+ GET_SOURCES_ATTEMPTS: "3"
+ CONFIGURE_BASE_FLAGS: --enable-asserts --cache-file cache/config.cache
+ CFLAGS_DEFAULT: -O0 -g -ggdb3 -Wall -Wextra
+
+# In this build we combine
+# * gcc
+# * check
+gcc/Stretch:
+ image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
+ script:
+ - export CFLAGS=$CFLAGS_DEFAULT
+ - ./bootstrap
+ - ./configure $CONFIGURE_BASE_FLAGS
+ - make -j$(nproc)
+ - make check
+ tags:
+ - shared
+ - linux
+ artifacts:
+ expire_in: 2 weeks
+ when: on_failure
+ paths:
+ - ./*.log
+ - src/*/*.log
+ - src/*/*/*.log
+
+# In this build we combine
+# * clang
+# * ASan, UBSan
+# * check
+Sanitizers/Stretch:
+ image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
+ script:
+ - export CFLAGS="$CFLAGS_DEFAULT -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address"
+ - ./bootstrap
+ - export CC="ccache clang"
+ - export UBSAN_OPTIONS=print_stacktrace=1
+ - export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.8/bin/llvm-symbolizer
+ - ./configure $CONFIGURE_BASE_FLAGS --disable-doc
+ - make check
+ tags:
+ - shared
+ - linux
+ artifacts:
+ expire_in: 2 weeks
+ when: on_failure
+ paths:
+ - ./*.log
+ - src/*/*.log
+ - src/*/*/*.log
+
+Scan-Build/Debian:
+ image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
+ script:
+ - export CFLAGS=$CFLAGS_DEFAULT
+ - ./bootstrap
+ - scan-build ./configure $CONFIGURE_BASE_FLAGS
+ - scan-build -v -enable-checker security,nullability --status-bugs -o scan-build make -j$(nproc)
+ - scan-build -v -enable-checker security,nullability --status-bugs -o scan-build make check
+ tags:
+ - shared
+ - linux
+ except:
+ - tags
+ artifacts:
+ expire_in: 2 weeks
+ when: on_failure
+ paths:
+ - scan-build/*
+
+MinGW/Debian:
+ image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$MINGW_BUILD
+ script:
+ - export CC="ccache $PREFIX-gcc"
+ - ./bootstrap
+ - ./configure $CONFIGURE_BASE_FLAGS --build=x86_64-pc-linux-gnu --host=$PREFIX
+ - make -j$(nproc)
+ tags:
+ - shared
+ - linux
+
+dist/Stretch:
+ image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_BUILD
+ script:
+ - export CFLAGS=$CFLAGS_DEFAULT
+ - ./bootstrap
+ - ./configure $CONFIGURE_BASE_FLAGS
+ - make -j$(nproc) dist
+ tags:
+ - shared
+ - linux
+ artifacts:
+ name: "$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
+ expire_in: 2 weeks
+ when: on_success
+ paths:
+ - ./libmicrohttpd-*.*.*.tar.??
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/.gitmodules
^
|
@@ -0,0 +1,3 @@
+[submodule "contrib/build-common"]
+ path = contrib/build-common
+ url = https://git.taler.net/build-common.git
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/ABOUT-NLS
^
|
(renamed from libmicrohttpd/po/ABOUT-NLS)
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/AUTHORS
^
|
@@ -57,6 +57,12 @@
Louis Benoit <louisbenoit@videotron.ca>
Flavio Coelin <flavio.ceolin@intel.com>
Silvio Clecio <silvioprog@gmail.com>
+Robert D Kosisko <rkocisko@gmail.com>
+Tal Moaz <tmoaz@cisco.com>
+Dirk Brinkmeier
+Jose Bollo <jobol@nonadev.net>
+Jonathan McDougall <jonathanmcdougall@gmail.com>
+Tim Ruhsen <tim.ruehsen@gmx.de>
Documentation contributions also came from:
Marco Maggi <marco.maggi-ipsu@poste.it>
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/COPYING
^
|
@@ -462,49 +462,3 @@
DAMAGES.
END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/ChangeLog
^
|
@@ -1,3 +1,720 @@
+Sun 25 Apr 2021 14:00:00 MSK
+ Releasing GNU libmicrohttpd 0.9.73. -EG
+
+Sat 24 Apr 2021 23:00:00 MSK
+ Fixed build with Clang and Visual Studio.
+ MSVS project files updated.
+ Enabled bind port autodetection with MSVS builds. -EG
+
+Fri 23 Apr 2021 14:27:00 MSK
+ Fixed build without TLS lib.
+ Fixed build without system poll() function.
+ Fixed compiler warnings on 32-bit platforms.
+ Fixed various compiler warnings. -EG
+
+Thu 22 Apr 2021 12:32:00 MSK
+ Fixed some typos.
+ Force disable TCP_CORK, TCP_NOPUSH, and TCP_NODELAY before switching
+ connection to "upgraded" mode.
+ Improved portability of the test-suite for upgraded connections. -EG
+
+Tue 20 Apr 2021 17:11:00 MSK
+ Disabled NLS by default in configure. -EG
+
+Mon 19 Apr 2021 18:58:00 MSK
+ Fixed testzzuf/test_put_chanked to correctly use MHD.
+ Added internal error code for TLS errors.
+ Added all missing messages to the .pot file.
+ Detect more types of errors for receiving data and report
+ error description in the MHD log.
+ Added support for ALPN on TLS connections if supported by
+ used TLS library. -EG
+
+Sun 18 Apr 2021 20:47:00 MSK
+ Removed dead code.
+ Limited iov-backed responses size to SSIZE_MAX as limited by
+ system calls.
+ Report error message in MHD log for send errors. -EG
+
+Sat 17 Apr 2021 18:50:00 MSK
+ Unified upgrade test behavior for all platforms.
+ Some code simplification and unification.
+ Compiler warning (false positive) fixed. -EG
+
+Fri 16 Apr 2021 17:58:00 MSK
+ Used run-time value if IOV_MAX if available.
+ Fixed portability of error handling for sending functions.
+ Detect pipes/unix sockets on fly and do not use TCP/IP specific
+ functions with them.
+ Fixed support of UNIX sockets on non-Linux kernels. -EG
+
+Fri 16 Apr 2021 10:23:39 AM CEST
+ Detect if a socket is a UNIX domain socket and do not try to play
+ with TCP corking options in this case (avoids useless failed
+ syscalls). -CG
+
+Thu 15 Apr 2021 18:56:00 MSK
+ Fixed configure '--enable-sanitizer' parameter.
+ Stopped pushing of partial responses when limited by system maximum size
+ for sendmsg(). -EG
+
+Web 14 Apr 2021 22:20:00 MSK
+ Fixed: use sendmsg() in POSIX-compatible way, do not try to send more
+ than IOV_MAX elements per single call. -EG
+
+Sun 11 Apr 2021 15:44:00 MSK
+ Updated test TLS certificates to not expired modern versions, restored
+ HTTPS examples compatibility with modern browsers.
+ TCP_NODELAY is not pre-enabled for HTTPS connection as it actually
+ does not speed-up TLS handshakes on moders OSes. -EG
+
+Thu 01 Apr 2021 21:29:46 MSK
+ Fixed MD5 digest authorization broken when compiled without variable
+ length arrays support (notably with MSVC).
+ Fixed and muted compiler warning.
+ Deeper test with zzuf if configured with --enable-heavy-tests.
+ Removed run-check of assert() in configure to avoid core dumps. -EG
+
+Thu 01 Apr 2021 17:46:00 MSK
+ Added new function MHD_run_wait() useful for single-threaded applications
+ without other network activity.
+ Added tests for the new function. -EG
+
+Wed 17 Mar 2021 20:53:33 MSK
+ Re-factored startup log parameters processing. Warn user if wrong logger
+ could be used potentially.
+ Added headers doxy with information about minimal MHD version when
+ particular symbols were introduced.
+ Added new daemon option to indicate SIGPIPE handling by application for
+ daemons being run in application thread. -EG
+
+Wed 24 Feb 2021 19:23:00 MSK
+ SIGPIPE-related macro minor refactoring for readability.
+ Added new response iov function (and related framework), based on the patch
+ provided by Lawrence Sebald and Damon N. Earp from NASA. -EG
+
+Thu 04 Feb 2021 06:41:34 PM CET
+ Fix PostProcessor to always properly stop iteration when application callback
+ tells it to do so. -CG
+
+Sun 24 Jan 2021 21:30:00 MSK
+ Added '--enable-heavy-tests' configure parameter.
+ Minor configure.ac and Makefiles fixes. -EG
+
+Tue 19 Jan 2021 17:59:00 MSK
+ Fixed compatibility with autoconf. 2.70
+ Updated M4 macros. -EG
+
+Wed 06 Jan 2021 08:39:58 PM CET
+ Return timeout of zero also for connections awaiting cleanup. -CG
+
+Tue 29 Dec 2020 15:39:00 MSK
+ Improved speed of TLS handshake by pre-enabling TCP_NODELAY. -EG
+
+Mon 28 Dec 2020 21:36:00 MSK
+ Releasing libmicrohttpd 0.9.72. -EG
+
+Mon 28 Dec 2020 09:37:00 MSK
+ Completely reworked and rewritten TCP_CORK, TCP_NOPUSH, TCP_NODELAY and
+ MSG_MORE handling. Reduced number of sys-calls, fixed portability for
+ FreeBSD, OpenBSD, NetBSD, Darwin, W32, Solaris.
+ Removed usage of gnutls_record_cork() as it fully blocks stream until
+ final block is ready.
+ Fixed compatibility with C90 compilers.
+ Really started using sendmsg() for header + body combined single-call
+ response sending.
+ Fixed sending of response body by sendmsg() when it shouldn't be sent,
+ like responses for HEAD requests.
+ Improved error handling for gnutls_record_send().
+ Updated W32 resources for .DLLs.
+ Fixed building with various disabled features (like messages, HTTPS,
+ http-upgrade, authorization etc.)
+ Fixed possible SIGPIPE generation when sendfile() is used (it was always
+ possible on Linux that sendfile() produce SIGPIPE, now it's fixed).
+ Several compiler warnings muted and/or fixed in the lib code and in
+ the examples. -EG
+
+Sun 01 Nov 2020 17:17:00 MSK
+ Fixed conflict with system CPU_COUNT macro.
+ Minor improvements of error reporting in MHD daemon.
+ Fixed FTBFS with GnuTLS versions before 3.1.9
+ Fixed test_add_conn for multi-CPU machines.
+ Fixed analyzer warnings.
+ Fixed use-after-free and resources leaks for upgraded connections
+ in TLS mode with thread-per-connection. -EG
+
+Sun 25 Oct 2020 19:31:00 MSK
+ Fixed epoll mode without listening socket.
+ Minor improvements of thread sync.
+ Fixed broken sendfile on FreeBSD.
+ Fixed broken MHD with thread-pool and without listening socket.
+ Added four tests for MHD_add_connection().
+ Fixed several resources leaks in error handlers.
+ Re-implemented scheme of handling of externally added connections,
+ fixed thread-safety. -EG
+
+Wed 21 Oct 2020 10:00:58 AM CEST
+ Corking should be OFF when sending the footer (#6610). -AP/CG
+
+Wed 07 Oct 2020 11:07:00 MSK
+ W32 default target version changed to Vista, XP is still supported.
+ Minor fixes and additional asserts for memorypool.
+ IPv6 tests are not used if IPv6 is disabled at run-time. -EG
+
+Sun 27 Sep 2020 10:08:03 PM CEST
+ Fixed incorrect triggering of epoll edge polling for
+ "upgraded" TLS connections. Fixed a few cases where
+ gnutls_record_uncork() return value was still ignored,
+ possibly causing buffer to not be flushed correctly. -CG
+
+Sat 26 Sep 2020 08:18:02 PM CEST
+ Make MHD_USE_NO_LISTEN_SOCKET work in conjunction with
+ MHD internal threads. -CG/DE
+
+Thu 24 Sep 2020 16:55:00 MSK
+ Fixed compiler warnings on W32.
+ Minor optimisation of MHD_YES/MHD_NO internal usage.
+ Refactor and cleanup of internal debugging macros.
+ Updated HTTP status codes, header names and methods from
+ the registries.
+ Fixed portability of test_upgrade_large.
+ Minor testsuite fixes.
+ Restored parallel build of libmicrohttpd (except tests). -EG
+
+Fri 11 Sep 2020 10:08:22 PM CEST
+ Fix crash problem in PostProcessor reported by MD. -CG
+ Fix GnuTLS configure test to check for gnutls_record_uncork. -CG
+
+Wed 19 Aug 2020 09:40:39 AM CEST
+ Add logic to check on MHD_pool_reallocate() failure reported on the
+ mailinglist (will NOT yet fix the issue). -CG
+
+Sun 26 Jul 2020 01:56:54 PM CEST
+ Add MHD_create_response_from_pipe() to allow creating a response based
+ on data read from a pipe. -CG
+
+Fri Jul 10 15:04:51 CEST 2020
+ Fixed Postprocessor URL-encoded parsing if '%' fell on boundary. -CG/MD
+
+Thu 02 Jul 2020 09:56:23 PM CEST
+ Fixed return type of MHD_queue_basic_auth_fail_response. -CA/CG
+
+Sun 28 Jun 2020 09:36:01 PM CEST
+ Fix buffer overflow issue in URL parser.
+ Releasing libmicrohttpd 0.9.71. -CG
+
+Tue 16 Jun 2020 08:44:22 PM CEST
+ Add logic to try again if GNUtls uncork() fails. -CG
+
+Wed 10 Jun 2020 09:44:29 PM CEST
+ Fixed PostProcessor bug discovered by MD, which given certain parser
+ boundaries caused the returned values to be wrong. -CG/MD
+
+Wed 08 Apr 2020 10:53:01 PM CEST
+ Introduce `enum MHD_Result` for #MHD_YES/#MHD_NO to avoid using 'int' so much.
+ Note that this change WILL cause compiler warnings until (most) MHD callbacks
+ in application code change their return type from 'int' to 'enum MHD_Result'.
+ That said, avoiding possible confusions of different enums is going to make
+ the code more robust in the future. For conditional compilation, test
+ for "MHD_VERSION >= 0x00097002". -CG
+
+Tue 07 Apr 2020 02:58:39 PM BRT
+ Fixed #5501 (Added example for how to provide a tiny threaded websocket server). -SC
+
+Tue 31 Mar 2020 02:36:40 PM BRT
+ Fixed #6142 (applied several spelling fixes). -DKG/-SC
+
+Sat 07 Mar 2020 05:20:33 PM CET
+ Fixed #6090 (misc. severe socket handling bugs on OS X). -CG
+
+Sat 08 Feb 2020 09:12:54 PM CET
+ Fixed 100-continue handling for PATCH method (#6068).
+ Fixed FTBFS from wrong #endif position for certain builds (#6025).
+ Fixed connection overflow issue when combining MHD_USE_NO_LISTEN_SOCKET
+ with MHD_USE_THREAD_PER_CONNECTION (#6036).
+ Updated m4 script to fix FTBFS when using -Werror=unused-but-set-parameter (#6078).
+ Releasing libmicrohttpd 0.9.70. -CG
+
+Thu Dec 26 14:43:27 CET 2019
+ Adding fix for urlencoding of keys without values in
+ post-processor logic. -CG
+
+Tue 24 Dec 2019 03:32:18 PM CET
+ Adding patch from Ethan Tuttle with test case for urlencoding
+ in post-processor for keys without values. -CG/ET
+
+Sun 15 Dec 2019 02:12:02 PM CET
+ Fix send() call (affects Mac OS X). #5977 -CG/fbrault
+ Releasing libmicrohttpd 0.9.69. -CG
+
+Fri 29 Nov 2019 11:22:25 PM CET
+ If application suspends a connection before we could send 100 CONTINUE,
+ give application another shot at queuing a reply before the upload begins. -CG
+
+Sat 26 Oct 2019 06:53:05 PM CEST
+ Fix regression where MHD would fail to return an empty response
+ when used with HTTPS.
+ Releasing libmicrohttpd 0.9.68. -CG/TR
+
+Fri 25 Oct 2019 02:31:59 PM CEST
+ Introduce MHD_RF_INSANITY_HEADER_CONTENT_LENGTH. -CG
+
+Thu 17 Oct 2019 04:50:52 PM CEST
+ Integrate 0-byte send() method for uncorking for old FreeBSD/OS X
+ systems into new mhd_send.c logic for uncorking.
+ Releasing libmicrohttpd 0.9.67. -CG
+
+Fri 18 Aug 2019 00:00:00 PM UTC
+ Fixes and optimizations for the setsockopt handling:
+ * Added: MHD_UPGRADE_ACTION_CORK_ON and MHD_UPGRADE_ACTION_CORK_OFF
+ to enum MHD_UpgradeAction (turn corking on/off on the underlying
+ socket).
+ * Use calls and flags native to the system for corking and
+ other operations, tested with performance improvements on
+ FreeBSD, Debian Linux, NetBSD, and cygwin. In particular,
+ this adds selective usage of MSG_MORE, NODELAY, TCP_NOPUSH,
+ TCP_CORK. -ng0
+
+Fri 09 Aug 2019 10:07:27 AM CEST
+ Copy compiler and linker hardening flags from GNUnet (updating
+ configure.ac). -CG
+
+Thu 01 Aug 2019 01:23:36 PM CEST
+ Releasing libmicrohttpd 0.9.66. -CG
+
+Thu 01 Aug 2019 12:53:49 AM CEST
+ Fix issue with discarding unhandled upload data discovered
+ by Florian Dold. -CG
+
+Mon 29 Jul 2019 08:01:50 PM CEST
+ Fix hanging situation with large transmission over upgraded
+ (i.e. Web socket) connection with epoll() and HTTPS enabled
+ (as reported by Viet on the mailinglist). -CG
+
+Thu 25 Jul 2019 02:40:12 PM CEST
+ Fixing regression introduced in cc5032b85 (bit mask matching
+ of the header kinds in MHD_lookup_connection_value()), as
+ reported by Jose Bollo on the mailinglist. -CG/JB
+
+Tue Jul 16 19:56:14 CEST 2019
+ Add MHD_OPTION_HTTPS_CERT_CALLBACK2 to allow OCSP stapling
+ and MHD_FEATURE_HTTPS_CERT_CALLBACK2 to check for. -TR
+
+Fri Jul 05 2019 22:30:40 MSK
+ Releasing libmicrohttpd 0.9.65. -EG
+
+Sun Jun 23 2019 21:27:43 MSK
+ Many fixes and improvements for connection-specific memory pool:
+ * Added asserts;
+ * Added testing of reallocation;
+ * Reallocation code rewritten to avoid extra allocation, when
+ possible to reuse already allocated memory;
+ * Large memory pools aligned to system page size;
+ * Large memory pools on W32 are cleared more securely after use,
+ optimised usage of system memory.
+ Better handled connection's memory shortage situations:
+ * error response could be sent to client even if all buffer space
+ was used;
+ * if buffer space become low when receiving, do not allocate last
+ buffer space and use small receive blocks instead.
+ Improved sending speed by using all available buffer space for
+ sending. -EG
+
+Sun Jun 09 2019 20:27:04 MSK
+ Releasing libmicrohttpd 0.9.64. -EG
+
+Sun Jun 09 2019 20:03:16 MSK
+ Updated HTTP headers, methods and status codes from registries,
+ Added scripts to import new headers, methods and status codes from
+ registries,
+ Minor doxyget comment fix,
+ Added missing MSVS project files to tarball.
+ Reodered includes in microhttpd.h -EG
+
+Mon 03 Jun 2019 11:45:52 PM CEST
+ Apply MHD_-prefix to hash functions, even if they are not in the
+ officially exported API. -CG/DB
+
+Sun Jun 02 01:52:11 MSK 2019
+ Support usage of SOCK_NOSIGPIPE on Solaris 11.4 and NetBSD 7+,
+ finally avoid SIGPIPE on Solaris. -EG
+
+Sat Jun 01 22:51:50 MSK 2019
+ Do not report errors if AF_UNIX socket is used on *BSD. -EG
+
+Thu May 30 23:32:09 MSK 2019
+ Improved detection of 'getsockname()' in configure.
+ Avoided using 'getsockname()' in code if not detected. -EG
+
+Sun May 26 23:32:49 MSK 2019
+ Fixed some tests on W32. -EG
+
+Sun May 26 23:05:42 MSK 2019
+ Better detection of sockaddr member in configure, fixed build on *BSD,
+ Fixed compiler warnings,
+ Updated and fixed libcurl tests. -EG
+
+Tue May 21 22:12:43 MSK 2019
+ Fixed doxygen comments,
+ Avoid dropping 'const' qualifier in macros,
+ Fixed some compiler warnings,
+ Properly support automatic port detections on some platforms,
+ Added checks for too long TLS parameters strings. -EG
+
+Tue May 21 17:52:48 MSK 2019
+ Spelling fixes. -EG
+
+Mon May 20 15:39:35 MSK 2019
+ Compiler warning fixes. -EG/CG
+ Fixed example for non-64bits platforms. -EG
+
+Wed May 15 23:51:49 MSK 2019
+ Optimized and improved processing speed by using precalculated and
+ already calculated lengths of strings. -EG
+
+Wed May 15 14:54:00 MSK 2019
+ Fixed build from source on GNU Hurd. -EG
+
+Mon May 6 11:58:00 MSK 2019
+ Updated README and COPYING files. MHD remains LGPLv2.1-licensed. -EG
+
+Fri May 3 20:08:00 MSK 2019
+ Store connection's keys and values with sizes;
+ Speedup keys search be comparing key length first;
+ Added functions for working with keys and values with binary zeros;
+ Fixed test_postprocessor_amp to fail on problems. -EG
+
+Wed May 1 16:40:00 MSK 2019
+ Reverted change of MHD_KeyValueIterator, implemented MHD_KeyValueIteratorN
+ with sizes for connection's key and value to get keys and values
+ with binary zeros. -EG
+
+Mon 29 Apr 2019 01:26:39 AM BRT
+ Fixed signed/unsigned comparison in example http_chunked_compression.c. -SC/TR
+
+Sun Apr 21 16:40:00 MSK 2019
+ Improved compatibility with MSVC compilers;
+ Fixed MHD compilation by Clang/LLVM in VS;
+ Used MSVC intrinsics for bit rotations and bytes swap;
+ Added project files for VS2019. -EG
+
+Fri Apr 19 23:00:00 MSK 2019
+ Rewritten SHA-256 calculations from scratch to avoid changing LGPL version;
+ Added usage of GCC/Clang built-ins for bytes swap to significantly improve
+ speed of MD5 and SHA-256 calculation on platforms with known endianness.
+ Added test for SHA-256 calculations. -EG
+
+Wed Apr 17 20:52:00 MSK 2019
+ Refactoring of mhd5.c: optimized, dead code removed;
+ Faster MD5 calculation on little endian platforms;
+ Bit manipulations moved to separate header file.
+ Added tests for MD5 calculations. -EG
+
+Mon 15 Apr 2019 05:33:52 PM CEST
+ Add MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT and
+ MHD_USE_INSECURE_TLS_EARLY_DATA flags. -CG
+
+Thu Apr 11 11:37:00 MSK 2019
+ Fixed MSVC 'Release' builds;
+ Fixed usage of MSVC's assert. -EG
+
+Wed Apr 10 14:31:00 MSK 2019
+ Improved shell compatibility for 'bootstrap', removed bash-ism.
+ Added wrapper script 'autogen.sh'. -EG
+
+Mon 08 Apr 2019 03:06:05 PM CEST
+ Fix close() checks as suggested by MK on the mailinglist
+ (#3926). -MK/CG
+
+Wed 20 Mar 2019 10:20:24 AM CET
+ Adding additional "value_length" argument to MHD_KeyValueIterator
+ callback to support binary zeros in values. This is done in a
+ backwards-compatible way, but may require adding a cast to existing
+ code to avoid a compiler warning. -CG
+
+Sun Feb 10 21:00:37 BRT 2019
+ Added example for how to compress a chunked HTTP response. -SC
+
+Sun 10 Feb 2019 05:03:44 PM CET
+ Releasing libmicrohttpd 0.9.63. -CG
+
+Sat 09 Feb 2019 01:51:02 PM CET
+ Extended test_get to test URI logging and query string parsing
+ to avoid regression fixed in previous patch in the future. -CG
+
+Thu Feb 7 16:16:12 CET 2019
+ Preliminary patch for the raw query string issue, to be tested. -CG
+
+Tue Jan 8 02:57:21 BRT 2019
+ Added minimal example for how to compress HTTP response. -SC
+
+Wed Dec 19 00:06:03 CET 2018
+ Check for GNUTLS_E_AGAIN instead of GNUTLS_E_INTERRUPTED when
+ giving up on a TLS connection. -LM/CG
+
+Thu Dec 13 22:48:14 CET 2018
+ Fix connection timeout logic if in thread-per-connection mode the
+ working thread takes longer than the timeout to queue the response. -CG
+
+Tue Dec 11 09:58:32 CET 2018
+ Add logic to avoid VLA arrays with compilers that do not support them. -CG
+
+Sat Dec 8 23:15:53 CET 2018
+ Fixed missing WSA_FLAG_OVERLAPPED which can cause W32 to block on
+ socket races when using threadpool. (See very detailed description
+ of the issue in the libmicrohttpd mailinglist post of today.) -JM
+
+Sat Dec 8 22:53:56 CET 2018
+ Added test for RFC 7616 and documented new API.
+ Releasing libmicrohttpd 0.9.62. -CG
+
+Sat Dec 8 17:34:58 CET 2018
+ Adding support for RFC 7616, experimental, needs
+ testing and documentation still! -CG
+
+Fri Dec 7 12:37:17 CET 2018
+ Add option to build MHD without any threads
+ and MHD_FEATURE_THREADS to test for it. -CG
+
+Thu Dec 6 13:25:08 BRT 2018
+ Renamed all occurrences from _model(s)_ to _mode(s)_. -SC
+
+Thu Dec 6 12:50:11 BRT 2018
+ Optimized the function MHD_create_response_from_callback() for
+ Windows by increasing its internal buffer size and allowed to customize
+ it via macro MHD_FD_BLOCK_SIZE. -SC
+
+Thu Dec 6 02:11:15 BRT 2018
+ Referenced the gnutls_load_file() function in the HTTPs examples. -SC
+
+Wed Dec 5 18:08:59 CET 2018
+ Fix regression causing URLs to be unescaped twice. -CG
+
+Sun Nov 18 13:08:11 CET 2018
+ Parse arguments with (properly) escaped URLs correctly.
+ (making things work with recent cURL changes, #5473).
+ Replace sprintf with snprintf in testcases.
+ Releasing libmicrohttpd 0.9.61. -CG
+
+Wed Nov 14 14:01:21 CET 2018
+ Fix build issue with GnuTLS < 3.0. -CG
+
+Mon Nov 12 19:50:43 CET 2018
+ Fix #5473 (test case failure due to change in libcurl). -eworm
+
+Thu Nov 8 14:53:27 CET 2018
+ Add MHD_create_response_from_buffer_with_free_callback. -CG
+
+Tue Nov 6 19:43:47 CET 2018
+ Upgrading to gettext 0.19.8.
+ Releasing libmicrohttpd 0.9.60. -CG
+
+Thu Nov 1 16:29:59 CET 2018
+ Enable using epoll() without listen socket. -JB
+
+Sat Oct 20 12:44:16 CEST 2018
+ In thread-per-connection mode, signal main thread for
+ thread termination for instant clean-up and application
+ notification about closed connections. -CG
+
+Tue Oct 16 20:43:41 CEST 2018
+ Add MHD_RF_HTTP_VERSION_1_0_RESPONSE option to make MHD
+ act more like an HTTP/1.0 server. -GH
+
+Fri Oct 5 18:44:45 CEST 2018
+ MHD_add_response_header() now prevents applications from
+ setting a "Transfer-Encoding" header to values other than
+ "identity" or "chunked" as other transfer encodings are
+ not supported by MHD. (Note that usually MHD will pick the
+ transfer encoding correctly automatically, but applications
+ can use the header to force a particular behavior.)
+ Fixing #5411 (never set Content-length if Transfer-Encoding
+ is given). -CG
+
+Sat Jul 14 11:42:15 CEST 2018
+ Add MHD_OPTION_GNUTLS_PSK_CRED_HANDLER to allow use of PSK with
+ TLS connections. -CG/TM
+
+Sat Jul 14 11:03:37 CEST 2018
+ Integrate patch for checking digest authentication based on
+ a digest, allowing servers to store passwords only hashed.
+ Adding new function MHD_digest_auth_check_digest(). -CG/DB
+
+Sat Mar 10 12:15:35 CET 2018
+ Upgrade to gettext-0.19.8.1. Switching to more canonical
+ gettext integration. -CG
+
+Fri Mar 2 21:44:24 CET 2018
+ Ensure MHD_RequestCompletedCallback is always called from
+ the correct thread (even on shutdown and for upgraded connections). -CG
+
+Tue Feb 27 23:27:02 CET 2018
+ Ensure MHD_RequestCompletedCallback is also called for
+ upgraded connections. -CG
+
+Fri Feb 16 03:09:33 CET 2018
+ Fixing #5278 as suggested by reporter. -CG/texec
+
+Thu Feb 1 10:12:22 CET 2018
+ Releasing GNU libicrohttpd 0.9.59. -CG
+
+Thu Feb 1 08:39:50 CET 2018
+ Fix masking operation. -CG/silvioprog
+
+Mon Jan 29 17:33:54 CET 2018
+ Fix deadlock when failing to prepare chunked response
+ (#5260). -CG/ghaderer
+
+Thu Jan 4 12:24:33 CET 2018
+ Fix __clang_major__ related warnings for non-clang
+ compilers reported by Tim on the mailinglist. -CG
+
+Mon Dec 11 17:11:00 MSK 2017
+ Fixed tests on platforms with huge number of CPUs.
+ Doxygen configuration was updated.
+ Various doxygen fixes. -EG
+
+Mon Dec 07 21:08:00 MSK 2017
+ Releasing GNU libmicrohttpd 0.9.58. -EG
+
+Mon Dec 07 16:01:00 MSK 2017
+ Fixed HTTPS tests on modern platforms. -EG
+
+Mon Dec 04 15:43:00 MSK 2017
+ Minor documentation installation fixes. -EG
+
+Mon Nov 27 22:58:38 CET 2017
+ Tolerate AF_UNIX when trying to determine our binding port
+ from socket. Use `sockaddr_storage` instead of trying to
+ guess the sockaddr type before calling getsockname(). -CG
+
+Mon Nov 27 22:24:00 MSK 2017
+ Releasing GNU libmicrohttpd 0.9.57. -EG
+
+Mon Nov 27 21:36:00 MSK 2017
+ Updated README. -EG
+
+Mon Nov 27 18:37:00 MSK 2017
+ Corrected names in W32 DLL resources.
+ Reordered and clarified configure summary message.
+ Additional compiler warning mutes for builds with various configure
+ parameters.
+ Fixed tests on Cygwin.
+ Used larger SETSIZE for Cygwin (same value as for native W32).
+ Minor fixes for Cygwin.
+ Added configure parameter to force disable usage of sendfile().
+ Minor testsuite fixes.
+ Really fixed builds with optimisation for size. -EG
+
+Sat Nov 25 18:37:00 MSK 2017
+ Fixed build with optimisation for size. -EG
+
+Fri Nov 24 20:14:02 CET 2017
+ Releasing GNU libmicrohttpd 0.9.56. -CG
+
+Thu Nov 23 17:40:00 MSK 2017
+ Added MHD_FEATURE_SENDFILE enum value and report. -EG
+
+Thu Nov 23 08:56:00 MSK 2017
+ Fixed receiving large requests in TLS mode with epoll.
+ Improved GnuTLS and libgcrypt detection in configure, do not ignore
+ flags in GNUTLS_{CFLAGS,LIBS} variables.
+ Added special trick for Solaris/Openindiana to find GnuTLS-3 with
+ right bitness.
+ Added support for Solaris sendfile(3) function.
+ Fixed dataraces with thread ID on W32 and pthread. Now check for
+ correct thread in MHD_queue_response() works correctly.
+ Fixed and silenced compiler warnings in tests and examples.
+ Removed usage of TLS flags in examples where TLS is not required.
+ Added support for MultiSSL in https tests with libcurl >= 7.56.0.
+ Improved detection of OFF_T_MAX, SIZE_MAX. Added macros for
+ SSIZE_MAX in mhd_limits.h. There are some platforms that really
+ require those macros.
+ Added support for Darwin's sendfile() function.
+ Updated .gitignore files.
+ Reworked mhd_sys_extentions.m4 with better support of modern
+ platforms, more reliable detection of required macros, and
+ detection of disabling of system-specific features by
+ _XOPEN_SOURCE macro. -EG
+
+Wed Nov 1 20:43:00 MSK 2017
+ Mixed and muted many compiler warnings. Now GCC's flags
+ -Wall -Wextra could be used for building.
+ Fixed compilation of examples without libmagic.
+ Better detection of libgnutls in configure.
+ Reworked launch of nested configure in "po" directory to
+ prevent useless reconfiguration.
+ Fixed some wrong asserts.
+ Enabled "test_options" test.
+ Use "test_start_stop" without libcurl.
+ Use chunks with sendfile() to prevent locking thread for
+ single connection with large file.
+ Added support for FreeBSD's sendfile with additional
+ optimisations for FreeBSD 11.
+ Refactoring and improvements for MHD_start_daemon_va() and
+ MHD_stop_daemon().
+ Fixed testing with GnuTLS >= 3.6.0. -EG
+
+Mon Oct 9 22:38:07 CEST 2017
+ Add MHD_free() to allow proper free()-ing of username/password
+ data returned via MHD_digest_auth_get_username() or
+ MHD_basic_auth_get_username_password() on Windows. -CG
+
+Tue Sep 26 14:00:58 CEST 2017
+ Fixing race involving setting "at_limit" flag. -CG
+
+Tue Sep 08 21:39:00 MSK 2017
+ Fixed build of examples when MHD build with non-pthread lib.
+ MHD_queue_response(): added check for using in correct thread.
+ Fixed sending responses larger 16 KiB in TLS mode with epoll.
+ Improved doxy for MHD_get_timeout() and related functions.
+ Minor internal refactoring. -EG
+
+Tue Jul 23 11:32:00 MSK 2017
+ Updated chunked_example.c to provide real illustration of usage of
+ chunked encoding. -EG
+
+Thu Jul 13 21:41:00 MSK 2017
+ Restored SIGPIPE suppression in TLS mode.
+ Added new value MHD_FEATURE_AUTOSUPPRESS_SIGPIPE so application could
+ check whether SIGPIPE handling is required.
+ Used GNUTLS_NONBLOCK for TLS sessions. -EG
+
+Tue Jun 20 23:52:00 MSK 2017
+ Libgcrypt is now optional and required only for old GnuTLS versions. -EG
+
+Wed Jun 14 21:42:00 MSK 2017
+ Added support for debug assert() and new configure parameter
+ --enable-asserts for debug builds.
+ Removed non-functional Symbian support. -EG
+
+Mon Jun 05 23:34:00 MSK 2017
+ More internal refactoring:
+ merged MHD_tls_connection_handle_read/write() with non-TLS version,
+ reduced and unified number of layers for network processing (before
+ refactoring MHD_tls_connection_handle_read->MHD_connection_handle_read->
+ do_read->recv_tls_adapter->GnuTLS->recv_param_adapter - 5 MHD layers;
+ after refactoring MHD_connection_handle_read->recv_tls_adapter->GnuTLS -
+ 2 MHD layers),
+ simplified and removed dead code from
+ MHD_connection_handle_read/write() without functional change. -EG
+
+Mon Jun 05 22:20:00 MSK 2017
+ Internal refactoring:
+ used TCP sockets directly with GnuTLS (performance improvement),
+ moved some connection-related code from daemon.c to
+ connection.c/connection_https.c,
+ removed hacks around sendfile() and implemented correct support of
+ sendfile(),
+ removed do_read() and do_write() to reduce number of layer around send()
+ and recv() and to improve readability and maintainability of code,
+ implemented separate tracking of TLS layer state, independent of HTTP
+ connection stage. -EG
+
+Sun Jun 04 15:02:00 MSK 2017
+ Improved thread-safety of MHD_add_connection() and
+ internal_add_connection(), minor optimisations. -EG
+
Sun May 28 23:26:00 MSK 2017
Releasing GNU libmicrohttpd 0.9.55. -EG
@@ -30,7 +747,7 @@
Do not add any "Connection" headers for "upgrade" connections. -EG
Wed May 10 23:09:00 MSK 2017
- Resume resuming connection before other processing in external polling
+ Resume resuming connection before other processing in external polling
mode. -EG
Tue May 9 23:16:00 MSK 2017
@@ -51,7 +768,7 @@
MHD_get_response_header(), match only headers (not footers). -EG
Fri May 5 20:57:00 MSK 2017
- Fixed null dereference when connection has "Upgrade" request and
+ Fixed null dereference when connection has "Upgrade" request and
connection is not upgraded. -JB/EG
Better handle Keep-Alive/Close. -EG
@@ -82,7 +799,7 @@
field names if MHD_USE_PEDANTIC_CHECKS is set. -CG
Sun Apr 23 19:20:33 CEST 2017
- Replace remaining occurences of sprintf() with
+ Replace remaining occurrences of sprintf() with
MHD_snprintf_(). Thanks to Ram for pointing this out. -CG
Sat Apr 22 20:39:00 MSK 2017
@@ -589,7 +1306,7 @@
Thu Feb 4 11:38:11 CET 2016
Added some buffer overrun protection.
- Fixed handling of misformed URI with spaces. -EG
+ Fixed handling of malformed URI with spaces. -EG
Wed Feb 3 15:41:57 CET 2016
Make signal-pipe non-blocking and drain it. -CG
@@ -681,7 +1398,7 @@
Wed Nov 25 17:02:53 CET 2015
Remove 200ms delay observable with keep-alive on Darwin
- and *BSD platfroms. -EG
+ and *BSD platforms. -EG
Tue Nov 10 15:25:48 CET 2015
Fix issue with shutdown if connection was resumed just
@@ -711,7 +1428,7 @@
Sun Oct 25 15:29:23 CET 2015
Fixing transient resource leak affecting long-lived
- connections with many keep-alives and HTTP request
+ connections with a lot of keep-alive and HTTP request
pipelining under certain circumstances (which reduced
the receive window).
Fixed assertion failure triggered by a race in
@@ -786,7 +1503,7 @@
Fri Jun 26 23:17:20 CEST 2015
Fix (automatic) handling of HEAD requests with
MHD_create_response_from_callback() and HTTP/1.1
- connection keep-alives. Thanks to Cristian Klein
+ connection keep-alive. Thanks to Cristian Klein
for reporting. -CG
Tue Jun 09 18:30:17 CEST 2015
@@ -1045,7 +1762,7 @@
Changed configure flag from '--disable-pipe' to
'--enable-socketpair'.
Added configure flags '--disable-doc' and '--disable-examples'.
- Narrowed down extrenal lib specific compiler and linker flags
+ Narrowed down external lib specific compiler and linker flags
usage. -EG
Wed Feb 26 17:42:34 CET 2014
@@ -1151,7 +1868,7 @@
Fri Nov 29 20:17:03 CET 2013
Eliminating theoretical stack overflow by limiting length
of URIs in authentication headers to 32k (only applicable
- if the application explicitly raised the memroy limits,
+ if the application explicitly raised the memory limits,
and only applies to MHD_digest_auth_check). Issue was
reported by Florian Weimer. -CG
@@ -1379,7 +2096,7 @@
at ~1500 MB/s on this system). -CG
Fri Mar 29 16:44:29 CET 2013
- Renaming testcases to consistenly begin with test_;
+ Renaming testcases to consistently begin with test_;
Changing build system to build examples in doc/.
Releasing libmicrohttpd 0.9.26. -CG
@@ -1526,7 +2243,7 @@
Tue May 29 13:45:15 CEST 2012
Fixing bug where MHD failed to call connection termination callback
if a connection either was closed due to read errors or if MHD
- was terminated with certain threading models. Added new
+ was terminated with certain threading modes. Added new
termination code MHD_REQUEST_TERMINATED_READ_ERROR for the
read-termination cause. -CG
@@ -2028,7 +2745,7 @@
aligned (fixes bus errors on Sparc). -CG
Thu Dec 17 20:26:52 CET 2009
- poll.h is not stricly required anymore. -ND
+ poll.h is not strictly required anymore. -ND
Fri Dec 4 13:17:50 CET 2009
Adding MHD_OPTION_ARRAY. -CG
@@ -2099,11 +2816,11 @@
Fri May 15 11:00:20 MDT 2009
Grow reserved read buffer more aggressively so that we are not
- needlessly stuck reading only a handfull of bytes in each iteration. -CG
+ needlessly stuck reading only a handful of bytes in each iteration. -CG
Thu May 14 21:20:30 MDT 2009
Fixed issue where the "NOTIFY_COMPLETED" handler could be called
- twice (if a socket error or timeout occured for a pipelined
+ twice (if a socket error or timeout occurred for a pipelined
connection after successfully completing a request and before
the next request was successfully transmitted). This could
confuse applications not expecting to see a connection "complete"
@@ -2267,7 +2984,7 @@
Fixed a problem (introduced in 0.2.3) with handling very
large requests (the code did not return proper error code).
If "--enable-messages" is specified, the code now includes
- reasonable default HTML webpages for various build-in
+ reasonable default HTML webpages for various built-in
errors (such as request too large and malformed requests).
Without that flag, the webpages returned will still be
empty.
@@ -2393,7 +3110,7 @@
HTTP 400 status back if this is violated). - CG
Tue Aug 21 01:01:46 MDT 2007
- Fixing assertion failure that occured when a client
+ Fixing assertion failure that occurred when a client
closed the connection after sending some data but
not the full headers. - CG
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/Makefile.am
^
|
@@ -1,8 +1,16 @@
# This Makefile.am is in the public domain
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = contrib m4 src .
-DIST_SUBDIRS = $(SUBDIRS) po
-EXTRA_PO_DIST = po/ABOUT-NLS $(top_srcdir)/po/configure.ac po/configure
+
+if HAVE_PO
+SUBDIRS += po
+endif
+
+if BUILD_DOC
+SUBDIRS += doc
+endif
+
+
W32COMMON = w32/common/gen_dll_res.ps1 w32/common/microhttpd_dll_res_vc.rc.in w32/common/microhttpd_dll_res_vc.rc \
w32/common/MHD_config.h w32/common/vs_dirs.props w32/common/common-build-settings.vcxproj \
w32/common/libmicrohttpd-build-settings.vcxproj w32/common/libmicrohttpd-files.vcxproj w32/common/libmicrohttpd-filters.vcxproj \
@@ -20,90 +28,14 @@
w32/VS2017/hellobrowser.vcxproj w32/VS2017/hellobrowser.vcxproj.filters \
w32/VS2017/simplepost.vcxproj w32/VS2017/largepost.vcxproj \
w32/VS2017/libmicrohttpd.sln
+W32VS2019 = w32/VS2019/libmicrohttpd.vcxproj w32/VS2019/libmicrohttpd.vcxproj.filters \
+ w32/VS2019/hellobrowser.vcxproj w32/VS2019/hellobrowser.vcxproj.filters \
+ w32/VS2019/simplepost.vcxproj w32/VS2019/largepost.vcxproj \
+ w32/VS2019/libmicrohttpd.sln
EXTRA_DIST = \
acinclude.m4 \
libmicrohttpd.pc.in \
- $(EXTRA_PO_DIST) \
- $(W32COMMON) $(W32VS2013) $(W32VS2015) $(W32VS2017)
+ $(W32COMMON) $(W32VS2013) $(W32VS2015) $(W32VS2017) $(W32VS2019)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmicrohttpd.pc
-
-if BUILD_DOC
-SUBDIRS += doc
-endif
-
-.PHONY: po-files update-po-files po-files-pre-distdir renew-po-configure.ac update-POTFILES.in
-
-# Do not override automake rule, only add prerequisite
-distdir@EMPTY_VAR@: po-files-pre-distdir
-
-# Do not override automake rule, only add prerequisite
-distclean-recursive@EMPTY_VAR@: po/Makefile
-
-srcdir_po = $(top_srcdir)/po
-
-# Test target: build main po file
-po-files: $(srcdir_po)/libmicrohttpd.pot
-
-# Test target: force update all po files
-update-po-files: po-files-pre-distdir Makefile
- @$(am__cd) po && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.pot-update
-
-# Update po-related files before make distdir
-po-files-pre-distdir: update-POTFILES.in renew-po-configure.ac
- @$(MAKE) $(AM_MAKEFLAGS) po/Makefile
-
-# Clean in po directory only if po/Makefile was generated to avoid
-# useless generation of po/Makefile only for 'clean' target
-clean-local:
- @ if test -f po/Makefile; then \
- $(MAKE) $(AM_MAKEFLAGS) po/Makefile && \
- $(am__cd) po && $(MAKE) $(AM_MAKEFLAGS) clean || exit 1; \
- fi;
-
-po/Makefile: $(srcdir_po)/Makefile.in.in $(srcdir_po)/Makevars $(srcdir_po)/POTFILES.in po/config.status
- @$(am__cd) po && @SHELL@ ./config.status ./Makefile.in po-directories
-
-# Regenerate po/config.status if this Makefile is changed as configure parameters may be updated
-po/config.status: $(srcdir_po)/configure Makefile
- @$(MKDIR_P) po && $(am__cd) po && echo "cd po && @SHELL@ ./configure @ac_configure_args@" && \
- @SHELL@ $(abs_top_srcdir)/po/configure @ac_configure_args@ --srcdir=$(abs_top_srcdir)/po \
- --disable-option-checking --no-create --no-recursion
-
-# Next rules actually create files in source tree, not in build tree, but those files should
-# stay in source tree and should be distributed in tarball, i.e. should not be created during
-# normal builds.
-$(srcdir_po)/libmicrohttpd.pot: po/Makefile
- @$(am__cd) po && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.pot
-
-# This target doesn't depend on po/configure.acT so po/configure.ac (and po/configure) will not be
-# forced to regenerate after each run of main configure.
-# If po/configure.ac is missing - it will be generated.
-$(srcdir_po)/configure.ac:
- @$(MAKE) $(AM_MAKEFLAGS) renew-po-configure.ac
-
-# Update po/configure.ac only if po/configure.acT (generated by main configure) is different.
-# If po/configure.ac is unchanged then po/configure will not be regenerated
-renew-po-configure.ac:
- @$(MAKE) $(AM_MAKEFLAGS) po/configure.acT && \
- if ! test -f $(srcdir_po)/configure.ac || \
- ! cmp -s po/configure.acT $(srcdir_po)/configure.ac ; then \
- echo "cp po/configure.acT $(srcdir_po)/configure.ac" && \
- cp po/configure.acT $(srcdir_po)/configure.ac || exit 1; \
- fi
-
-$(srcdir_po)/configure: $(srcdir_po)/configure.ac
- @$(am__cd) $(srcdir_po) && echo "Creating po/configure..." && \
- echo "@ACLOCAL@" && @ACLOCAL@ && \
- echo "@AUTOCONF@" && @AUTOCONF@
-
-# Generate po/POTFILES.in if po/POTFILES.in is missing
-$(srcdir_po)/POTFILES.in:
- @$(MAKE) $(AM_MAKEFLAGS) update-POTFILES.in
-
-update-POTFILES.in:
- @$(am__cd) $(srcdir_po) && echo @ECHO_N@ "Creating po/POTFILES.in... @ECHO_C@" && chmod o+w . && \
- find '../src/include' ! -name 'include' -prune -name '*.h' ! -name 'mhd_options.h' > POTFILES.in && \
- find '../src/microhttpd' ! -name 'microhttpd' -prune \( -name '*.h' -o -name '*.c' \) ! -name 'test_*' >> POTFILES.in && \
- echo "@ECHO_T@done." || (rm -f POTFILES.in ; echo "@ECHO_T@failed." && false)
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/NEWS
^
|
@@ -1,2 +1,86 @@
+Sun 25 Apr 2021 14:00:00 MSK
+Released GNU libmicrohttpd 0.9.73
+
+ This release brings new features, improvements, and a few fixes.
+ The most important addition is the new function for vector-backed
+ responses, based on the patch contributed by NASA engineers.
+ Other changes include compatibility with autoconf 2.70+, improved
+ testsuite compatibility with CI systems, fixed and improved MSVC
+ builds, and implemention of ALPN support.
+
+ More detailed list of notable changes:
+
+ API changes:
+ + Added new function MHD_create_response_from_iovec(), based on the
+ patch provided by Lawrence Sebald and Damon N. Earp from NASA.
+ + Added MHD_OPTION_SIGPIPE_HANDLED_BY_APP daemon option.
+ + Added new function MHD_run_wait().
+ + Added MHD_OPTION_TLS_NO_ALPN to disable usage of ALPN even if
+ it is supported by TLS library.
+
+ New features:
+ + Added '--enable-heavy-tests' configure parameter (disabled by
+ default).
+ + Implemented support for ALPN.
+
+ Improvements and enhancements:
+ * Return timeout of zero also for connections awaiting cleanup.
+ * Compatibility with autoconf >=2.70, used new autoconf features.
+ * Warn user when custom logger option is not the first option.
+ * Added information to the header about minimal MHD version when
+ particular symbols were introduced.
+ * Updated test certificates to be compatible with modern browsers.
+ * Added on-fly detection of UNIX domain sockets and pipes, MHD does
+ not try to use TCP/IP-specific socket options on them.
+ * Report more detailed error description in the MHD log for send
+ and receive errors.
+ * Enabled bind port autodetection for MSVC builds.
+
+ Fixes:
+ # Fix PostProcessor to always properly stop iteration when
+ application callback tells it to do so.
+ # Fixed MD5 digest authorization broken when compiled without
+ variable length arrays support (notably with MSVC).
+ # Fixed detection of type of send errors on W32.
+
+ -- Evgeny Grin (Karlson2k)
+
+
+Mon 28 Dec 2020 21:36:00 MSK
+Released GNU libmicrohttpd 0.9.72
+
+ This release is mostly a bugfix release, with greatly improved
+ compatibility with various OSes/kernels, including FreeBSD, Windows,
+ OpenBSD, NetBSD, Darwin (macOS), Solaris. Performance is improved,
+ especially with HTTPS connections and stay-alive HTTP connections.
+
+ Notable changes since version 0.9.71:
+
+ API changes:
+ + New function MHD_create_response_from_pipe()
+
+ Improvements and enhancements:
+ * Fully rewritten code for buffering/pushing from kernel network buffers
+ for compatibility with various OSes. Reduced number of additional
+ sys-calls, network is better utilized, responses are delivered faster.
+ * Restored optimal sendfile() usage on FreeBSD.
+ * MHD now takes care about SIGPIPE handling by blocking it in internal
+ threads and avoiding functions (like sendfile()) that could generate
+ SIGPIPE when blocking of this signal is not possible.
+
+ Fixes:
+ # Fixed crash in PostProcessor.
+ # Fixed several resources leaks in corner cases.
+ # Improved thread sync, thread safety and fixed one use-after-free under
+ special conditions during stopping of daemon.
+ # Updated HTTP status codes, header names and methods from the
+ registries.
+ # Fixed functioning without listen socket and with internal threads.
+ # Fixed streaming of chunked responses for both HTTP and HTTPS.
+ # Various compatibility fixes.
+
+ -- Evgeny Grin (Karlson2k)
+
+
Tue Jan 9 20:52:48 MST 2007
Project posted.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/README
^
|
@@ -7,11 +7,16 @@
protocol. The main application must still provide the application
logic to generate the content.
+GNU libmicrohttpd is dual-licensed under the GNU Lesser General Public
+License (LGPLv2.1+) and the eCos License. See COPYING for details.
+
Installation
============
-If you are using Subversion, run "autoreconf -fi" to create configure.
+See INSTALL for generic installation instructions.
+
+If you are using Git, run "autoreconf -fi" to create configure.
In order to run the testcases, you need a recent version of libcurl.
libcurl is not required if you just want to install the library.
@@ -46,12 +51,10 @@
least). On other systems that may trigger a SIGPIPE on send/recv, the
main application should install a signal handler to handle SIGPIPE.
-libmicrohttpd should work well on GNU/Linux, BSD, OS X, W32 and z/OS.
+libmicrohttpd should work well on GNU/Linux, W32, FreeBSD, Darwin,
+NetBSD, OpenBSD, Solaris/OpenIndiana, and z/OS.
Note that HTTPS is not supported on z/OS (yet). We also have reports
-of users using it on vxWorks and Symbian. Note that on platforms
-where the compiler does not support the "constructor" attribute, you
-must call "MHD_init" before using any MHD functions and "MHD_fini"
-after you are done using MHD.
+of users using it on vxWorks.
Development Status
@@ -74,3 +77,13 @@
- parse_options (daemon.c)
- MHD_set_panic_func (daemon.c)
- MHD_get_version (daemon.c)
+
+
+Note that the working library is in src/microhttpd/ with the API in
+src/include/microhttpd.h. An *experimental* (read: not yet working
+at all) newer implementation is in src/lib/, with the new API in
+src/include/microhttpd2.h. The experimental code will need MUCH
+more testing and development, you are strongly advised to stick
+to microhttpd.h unless you are a MHD developer!
+
+
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/autogen.sh
^
|
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# This file was added for compatibility with some automated build systems.
+# It is recommended to use 'bootstrap' directly instead.
+
+ag_srcdir="${0%/*}" && ag_srcdir="${ag_srcdir}${ag_srcdir:+/}"
+"${ag_srcdir}bootstrap" ${1+"$@"}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/bootstrap
^
|
@@ -1,6 +1,51 @@
#!/bin/sh
-if ! test -n "$BASH_SOURCE" || ! workdir="${BASH_SOURCE[0]%/*}" || ! test -n "$workdir" || ! cd "$workdir"; then
- workdir=`dirname "$0"` && test -n "$workdir" && cd "$workdir" || echo "Warning: can't get working directory" 1>&2
+unset bs_srcdir
+if test X"`dirname / 2>/dev/null`" = X"/"; then
+ bs_scrdir=`dirname $0`
+else
+ bs_scrdir="${0%/*}"
+fi
+
+test -n "$bs_scrdir" && cd "$bs_scrdir" || echo "Warning: cannot get sources directory" 1>&2
+
+# This is more portable than `which' but comes with
+# the caveat of not(?) properly working on busybox's ash:
+existence()
+{
+ command -v "$1" >/dev/null 2>&1
+}
+
+
+if existence uncrustify; then
+ echo "Installing uncrustify hook and configuration"
+ # Install uncrustify format symlink (if possible)
+ ln -s contrib/uncrustify.cfg uncrustify.cfg 2> /dev/null
+ # Install pre-commit hook (if possible)
+ ln -s ../../contrib/uncrustify_precommit .git/hooks/pre-commit 2> /dev/null
+else
+ echo "Uncrustify not detected, hook not installed. Please install uncrustify if you plan on doing development"
+fi
+
+if existence libtool || existence libtoolize || existence glibtoolize || existence slibtool; then
+ echo "Running autotools..."
+ aclocal -I m4 --install && \
+ libtoolize -c -i -v && \
+ autoconf && \
+ autoheader && \
+ automake -a -c --gnu
+ if test $? -ne 0 || ! test -x configure || ! test -f Makefile.in ; then
+ echo "Autotools failed, retrying with autoreconf..."
+ if ! autoreconf -i ${1+"$@"} ; then
+ echo "Failed to autoreconf, retrying with force install..."
+ rm m4/po.m4 # Version of po.m4 should match installed po/* files
+ if ! autoreconf -i -f ${1+"$@"} ; then
+ echo "*** Failed to create 'configure' and other autotools generated files. ***" >&2
+ exit 1
+ fi
+ fi
+ fi
+ echo "The ${bs_scrdir-.}/configure is ready to run."
+else
+ echo "*** No libtoolize (libtool) or libtool found, please install it ***" >&2;
+ exit 1
fi
-aclocal -I m4 --install
-autoreconf -I m4 -f -i
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/build-aux/config.rpath
^
|
@@ -0,0 +1,684 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2016 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ nagfor*)
+ wl='-Wl,-Wl,,'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ wl=
+ ;;
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ newsos6)
+ ;;
+ *nto* | *qnx*)
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ wl='-Qoption ld '
+ ;;
+ *)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ haiku*)
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc)
+ ;;
+ m68k)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd2.[01]*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ *nto* | *qnx*)
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ case "$host_cpu" in
+ powerpc*)
+ library_names_spec='$libname$shrext' ;;
+ m68k)
+ library_names_spec='$libname.a' ;;
+ esac
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd[23].*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ freebsd* | dragonfly*)
+ library_names_spec='$libname$shrext'
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ haiku*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ *nto* | *qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ tpf*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/config.rpath
^
|
@@ -2,7 +2,7 @@
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
-# Copyright 1996-2016 Free Software Foundation, Inc.
+# Copyright 1996-2013 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
@@ -367,7 +367,11 @@
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
- freebsd2.[01]*)
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
@@ -544,11 +548,13 @@
dgux*)
library_names_spec='$libname$shrext'
;;
- freebsd[23].*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
freebsd* | dragonfly*)
- library_names_spec='$libname$shrext'
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
;;
gnu*)
library_names_spec='$libname$shrext'
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/configure.ac
^
|
@@ -1,5 +1,5 @@
# This file is part of libmicrohttpd.
-# (C) 2006-2017 Christian Grothoff (and other contributing authors)
+# (C) 2006-2020 Christian Grothoff (and other contributing authors)
#
# libmicrohttpd is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
@@ -22,59 +22,118 @@
#
AC_PREREQ([2.64])
LT_PREREQ([2.4.0])
-AC_INIT([GNU Libmicrohttpd],[0.9.55],[libmicrohttpd@gnu.org])
+AC_INIT([GNU Libmicrohttpd],[0.9.73],[libmicrohttpd@gnu.org])
+AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([silent-rules] [subdir-objects])
AC_CONFIG_HEADERS([MHD_config.h])
AC_CONFIG_MACRO_DIR([m4])
-LIB_VERSION_CURRENT=55
+LIB_VERSION_CURRENT=70
LIB_VERSION_REVISION=0
-LIB_VERSION_AGE=43
+LIB_VERSION_AGE=58
AC_SUBST(LIB_VERSION_CURRENT)
AC_SUBST(LIB_VERSION_REVISION)
AC_SUBST(LIB_VERSION_AGE)
AC_MSG_CHECKING([[whether z/OS special settings are required]])
-if test `uname -s` = "OS/390"
-then
+AS_IF([test `uname -s` = "OS/390"],
+[
# configure binaries for z/OS
- if test -z "$CC"
- then
- CC=`pwd`"/contrib/xcc"
- chmod +x $CC || true
- fi
- if test -z "$CPP"
- then
- CPP="c89 -E"
- fi
- if test -z "$CXXCPP"
- then
- CXXCPP="c++ -E -+"
- fi
+ AS_IF([test -z "$CC"],
+ [CC=`pwd`"/contrib/xcc"
+ chmod +x $CC || true])
+ AS_IF([test -z "$CPP"],
+ CPP="c89 -E")
+ AS_IF([test -z "$CXXCPP"],
+ CXXCPP="c++ -E -+")
AC_MSG_RESULT([[yes]])
# _CCC_CCMODE=1
# _C89_CCMODE=1
-else
+],
AC_MSG_RESULT([[no]])
-fi
+)
# Checks for programs.
AC_PROG_AWK
+AC_PROG_GREP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_CANONICAL_HOST
+m4_version_prereq([2.70],
+ [
+# Find C compiler and compiler options to support
+# the latest C standard (C11). Fallback to C99 and C89
+# if later C versions are not supported.
+AC_PROG_CC
+ ],
+ [
+# Find C compiler and compiler options to support
+# the latest C standard (C99). Fallback to C89
+# if later C versions are not supported.
AC_PROG_CC_STDC
+ ]
+)
MHD_SYS_EXT
LT_INIT([win32-dll])
LT_LANG([Windows Resource])
+# Checks for gettext.
+m4_ifdef([AM_GNU_GETTEXT], [
+ AS_VAR_SET_IF([enable_nls], [], [[enable_nls=no]])
+ AM_GNU_GETTEXT([external],[need-ngettext])
+ AC_CONFIG_FILES([po/Makefile.in])
+ have_po=yes
+], [
+ have_po=no
+])
+m4_ifdef([AM_GNU_GETTEXT_VERSION], [
+#do not indent here
+AM_GNU_GETTEXT_VERSION([0.20.2])
+])
+AM_CONDITIONAL([HAVE_PO], [ test "$have_po" = yes ])
+
+
+
+
+# Adam shostack suggests the following for Windows:
+# -D_FORTIFY_SOURCE=2 -fstack-protector-all
+AC_ARG_ENABLE([gcc-hardening],
+ [AS_HELP_STRING([--enable-gcc-hardening], [enable compiler security checks])],
+[AS_IF([test x$enableval = xyes],[
+ CFLAGS="$CFLAGS -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all"
+ CFLAGS="$CFLAGS -fwrapv -fPIE -Wstack-protector"
+ CFLAGS="$CFLAGS --param ssp-buffer-size=1"
+ LDFLAGS="$LDFLAGS -pie"
+ ])])
+
+# Linker hardening options
+# Currently these options are ELF specific - you can't use this with MacOSX
+AC_ARG_ENABLE([linker-hardening],
+ [AS_HELP_STRING([--enable-linker-hardening], [enable linker security fixups])],
+[AS_IF([test x$enableval = xyes],
+ [LDFLAGS="$LDFLAGS -z relro -z now"])])
+
+
+AC_ARG_ENABLE([sanitizer],
+ [AS_HELP_STRING([--enable-sanitizer], [enable Address Sanitizer and Undefined Behavior Sanitizer])],
+[AS_IF([test x$enableval = xyes],[
+ CFLAGS="$CFLAGS -fsanitize=address,undefined -fno-omit-frame-pointer"
+ ])])
+
+
+
+# Workaround for libgcrypt
+AS_IF([[test "x$lt_sysroot" != "x" && test "x$SYSROOT" = "x"]], [[SYSROOT="$lt_sysroot"]])
+
PACKAGE_VERSION_MAJOR='m4_car(m4_unquote(m4_split(AC_PACKAGE_VERSION, [\.])))'
PACKAGE_VERSION_MINOR='m4_argn(2, m4_unquote(m4_split(AC_PACKAGE_VERSION, [\.])))'
PACKAGE_VERSION_SUBMINOR='m4_argn(3, m4_unquote(m4_split(AC_PACKAGE_VERSION, [\.])))'
+AS_VAR_ARITH([MHD_W32_DLL_SUFF],[[$LIB_VERSION_CURRENT - $LIB_VERSION_AGE]])
AC_SUBST([PACKAGE_VERSION_MAJOR])
AC_SUBST([PACKAGE_VERSION_MINOR])
AC_SUBST([PACKAGE_VERSION_SUBMINOR])
+AC_SUBST([MHD_W32_DLL_SUFF])
AC_CONFIG_FILES([src/microhttpd/microhttpd_dll_res.rc])
MHD_LIB_CPPFLAGS=""
@@ -198,7 +257,7 @@
CFLAGS="$save_CFLAGS"
],
[[errattr_CFLAGS=""]], [], [])
-AC_MSG_CHECKING([[for function inline keywords suppoted by $CC]])
+AC_MSG_CHECKING([[for function inline keywords supported by $CC]])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $errattr_CFLAGS"
inln_prfx="none"
@@ -241,7 +300,9 @@
AS_IF([[test "x$inln_prfx" != "xnone"]],
[
AC_DEFINE([INLINE_FUNC],[1],[Define to 1 if your C compiler supports inline functions.])
- AC_DEFINE_UNQUOTED([_MHD_inline],[static $inln_prfx],[Define to prefix which will be used with MHD inline functions.])
+ AC_DEFINE_UNQUOTED([_MHD_static_inline],[static $inln_prfx],[Define to prefix which will be used with MHD static inline functions.])
+ ], [
+ AC_DEFINE([_MHD_static_inline],[static],[Define to prefix which will be used with MHD static inline functions.])
])
AC_MSG_RESULT([[$inln_prfx]])
CFLAGS="$save_CFLAGS"
@@ -249,113 +310,291 @@
# Check system type
shutdown_trig_select='no'
AC_MSG_CHECKING([[for target host OS]])
-case "$host_os" in
-*darwin* | *rhapsody* | *macosx*)
- AC_DEFINE_UNQUOTED(OSX,1,[This is an OS X system])
+AS_CASE(["$host_os"],
+ [*darwin* | *rhapsody* | *macosx*],
+ [AC_DEFINE_UNQUOTED(OSX,1,[This is an OS X system])
CFLAGS="-no-cpp-precomp -fno-common $CFLAGS"
mhd_host_os='Darwin'
- AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-freebsd*)
- AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [freebsd*],
+ [AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
AC_DEFINE_UNQUOTED(FREEBSD,1,[This is a FreeBSD system])
mhd_host_os='FreeBSD'
- AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-openbsd*)
- AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [openbsd*],
+ [AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
AC_DEFINE_UNQUOTED(OPENBSD,1,[This is an OpenBSD system])
mhd_host_os='OpenBSD'
- AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-netbsd*)
- AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [netbsd*],
+ [AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
AC_DEFINE_UNQUOTED(NETBSD,1,[This is a NetBSD system])
mhd_host_os='NetBSD'
- AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-*solaris*)
- AC_DEFINE_UNQUOTED(SOLARIS,1,[This is a Solaris system])
- AC_DEFINE_UNQUOTED(_REENTRANT,1,[Need with solaris or errno doesnt work])
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [*solaris*],
+ [AC_DEFINE_UNQUOTED(SOLARIS,1,[This is a Solaris system])
+ AC_DEFINE_UNQUOTED(_REENTRANT,1,[Need with solaris or errno does not work])
mhd_host_os='Solaris'
AC_MSG_RESULT([[$mhd_host_os]])
AC_SEARCH_LIBS(gethostbyname, nsl)
- AC_SEARCH_LIBS(socket, socket)
- ;;
-*arm-linux*)
- AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux kernel])
+ AC_SEARCH_LIBS(socket, socket)],
+ [*arm-linux*],
+ [AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux kernel])
mhd_host_os='ARM Linux'
AC_MSG_RESULT([[$mhd_host_os]])
- CFLAGS="-fPIC -pipe $CFLAGS"
- ;;
-*linux*)
- AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux kernel])
+ CFLAGS="-fPIC -pipe $CFLAGS"],
+ [*linux*],
+ [AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux kernel])
mhd_host_os='Linux'
- AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-*cygwin*)
- AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [*cygwin*],
+ [AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
mhd_host_os='Windows (Cygwin)'
AC_MSG_RESULT([[$mhd_host_os]])
- os_is_windows=yes
- ;;
-*mingw*)
- AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
+ os_is_windows=yes],
+ [*mingw*],
+ [AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
mhd_host_os='Windows (MinGW)'
AC_MSG_RESULT([[$mhd_host_os]])
LIBS="$LIBS -lws2_32"
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h], [], [AC_MSG_ERROR([[Winsock2 headers are required for W32]])], [AC_INCLUDES_DEFAULT])
AC_CACHE_CHECK([for MS lib utility], [ac_cv_use_ms_lib_tool],
- [[mslibcheck=`lib 2>&1`
- if [[ $mslibcheck = "Microsoft (R) Library Manager"* ]]; then
- ac_cv_use_ms_lib_tool=yes
- else
- ac_cv_use_ms_lib_tool=no
- fi
- ]])
- if test "x$ac_cv_use_ms_lib_tool" = "xyes"; then
- AC_SUBST([MS_LIB_TOOL], [[lib]])
- fi
+ [mslibcheck=`lib 2>&1`
+ AS_IF([echo "$mslibcheck" | $GREP -e '^Microsoft (R) Library Manager' - >/dev/null],
+ [ac_cv_use_ms_lib_tool=yes],
+ [ac_cv_use_ms_lib_tool=no])
+ ])
+ AS_IF([test "x$ac_cv_use_ms_lib_tool" = "xyes"],
+ [AC_SUBST([MS_LIB_TOOL], [[lib]])])
AC_SUBST([lt_cv_objdir])
os_is_windows=yes
os_is_native_w32=yes
- ;;
-*openedition*)
- AC_DEFINE_UNQUOTED(OS390,1,[This is a OS/390 system])
+ ],
+ [*openedition*],
+ [AC_DEFINE_UNQUOTED(OS390,1,[This is a OS/390 system])
mhd_host_os='OS/390'
+ AC_MSG_RESULT([[$mhd_host_os]])],
+ [gnu*],
+ [AC_DEFINE([[GNU_HURD]], [[1]], [Define to `1' if host machine runs on GNU Hurd.])
+ mhd_host_os='GNU Hurd'
AC_MSG_RESULT([[$mhd_host_os]])
- ;;
-*)
+ ],
+ [
mhd_host_os='unrecognised OS'
AC_MSG_RESULT([[$mhd_host_os]])
AC_MSG_WARN([Unrecognised OS $host_os])
AC_DEFINE_UNQUOTED(OTHEROS,1,[Some strange OS])
-# You might want to find out if your OS supports shutdown on listen sockets,
-# and extend the switch statement; if we do not have 'HAVE_LISTEN_SHUTDOWN',
-# pipes are used instead to signal 'select'.
-# AC_DEFINE_UNQUOTED(HAVE_LISTEN_SHUTDOWN,1,[can use shutdown on listen sockets])
-;;
-esac
+ ])
+
+AM_CONDITIONAL([CYGWIN_TARGET], [[test "x$os_is_windows" = "xyes" && \
+ test "x${os_is_native_w32}" != "xyes"]])
+
+AS_VAR_IF([os_is_windows], ["yes"],
+ [
+ AC_MSG_CHECKING([[whether target W32 version is specified by precomiler defines]])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+/* Note: check logic is reversed for easy log reading */
+#ifdef WINVER
+#error WINVER is defined
+choke me now;
+#endif
+#ifdef _WIN32_WINNT
+#error _WIN32_WINNT is defined
+choke me now;
+#endif
+#ifdef NTDDI
+#error NTDDI is defined
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [[mhd_w32_ver_preselect=no]], [[mhd_w32_ver_preselect=yes]]
+ )
+ AC_MSG_RESULT([[${mhd_w32_ver_preselect}]])
+ AC_CHECK_HEADERS([windows.h sdkddkver.h], [], [], [AC_INCLUDES_DEFAULT])
+ AS_VAR_IF([mhd_w32_ver_preselect],["yes"],
+ [
+ AC_MSG_CHECKING([[for specified target W32 version]])
+ AS_UNSET([[mhd_w32_ver]])
+ AS_UNSET([[mhd_w32_ver_msg]])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if _WIN32_WINNT+0 < 0x0501
+/* Check before headers inclusion */
+#error _WIN32_WINNT is less than 0x0501
+choke me now;
+#endif
+
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if _WIN32_WINNT+0 < 0x0501
+#error _WIN32_WINNT is less than 0x0501
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [], [
+ AC_MSG_RESULT([[pre-WinXP]])
+ AC_MSG_ERROR([[libmicrohttpd cannot be compiled for Windows version before Windows XP]])
+ ]
+ )
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if _WIN32_WINNT+0 == 0x0501
+#error _WIN32_WINNT is 0x0501
+choke me now;
+#endif
+#if _WIN32_WINNT+0 == 0x0502
+#error _WIN32_WINNT is 0x0502
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [], [
+ mhd_w32_ver="WinXP"
+ mhd_w32_ver_msg="WinXP (selected by precompiler flags)"
+ ]
+ )
+ AS_VAR_SET_IF([mhd_w32_ver], [],
+ [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if _WIN32_WINNT+0 < 0x0600
+#error _WIN32_WINNT is less than 0x0600 but greater than 0x0502
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [], [
+ AC_MSG_ERROR([[_WIN32_WINNT value is wrong (less than 0x0600 but greater than 0x0502)]])
+ ]
+ )
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if _WIN32_WINNT+0 == 0x0600
+#error _WIN32_WINNT is 0x0600
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [], [
+ mhd_w32_ver="Vista"
+ mhd_w32_ver_msg="Vista (selected by precompiler flags)"
+ ]
+ )
+ ]
+ )
+
+ AS_VAR_SET_IF([mhd_w32_ver], [],
+ [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if _WIN32_WINNT+0 > 0x0600
+#error _WIN32_WINNT is greater than 0x0600
+choke me now;
+#endif
+ ]],[[(void)0]])
+ ], [
+ mhd_w32_ver="unknown"
+ mhd_w32_ver_msg="unknown (cannot be detected)"
+ ], [
+ mhd_w32_ver="newer than Vista"
+ mhd_w32_ver_msg="newer than Vista (selected by precompiler flags)"
+ ]
+ )
+ ]
+ )
+ AC_MSG_RESULT([[${mhd_w32_ver}]])
+ ], [
+ mhd_w32_ver="Vista"
+ mhd_w32_ver_msg="Vista (default, override by CPPFLAGS=-D_WIN32_WINNT=0xNNNN)"
+ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
+ AC_MSG_CHECKING([[whether headers accept _WIN32_WINNT=0x0600]])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SDKDDKVER_H
+#include <sdkddkver.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#include <stdio.h>
+ ]],[[(void)0]])
+ ], [
+ AC_MSG_RESULT([[yes]])
+ ], [
+ AC_MSG_RESULT([[no]])
+ AC_MSG_ERROR([Headers do not accept _WIN32_WINNT=0x0600. Consider override target W32 version by CPPFLAGS=-D_WIN32_WINNT=0xNNNN])
+ ]
+ )
+ ]
+ )
+ ]
+)
AC_ARG_WITH([threads],
- [AS_HELP_STRING([--with-threads=LIB],[choose threading library (posix, w32, auto) [auto]])],
+ [AS_HELP_STRING([--with-threads=LIB],[choose threading library (posix, w32, auto, none) [auto]])],
[], [with_threads='auto'])
AS_CASE([[$with_threads]],
[[win32]], [[with_threads='w32']],
[[pthreads]], [[with_threads='posix']],
[[posix]], [[:]],
[[w32]], [[:]],
+ [[none]], [[with_threads='none']],
+ [[no]], [[with_threads='none']],
[[auto]], [[:]],
[AC_MSG_ERROR([[incorrect parameter "$with_threads" specified for --with-threads]])]
)
# Check for posix threads support, regardless of configure parameters as
-# testsuite use only posix threads.
+# testsuite uses only posix threads.
AX_PTHREAD(
[
mhd_have_posix_threads='yes'
AC_DEFINE([[HAVE_PTHREAD_H]],[[1]],[Define to 1 if you have the <pthread.h> header file.])
+ AC_CACHE_CHECK([[whether pthread_sigmask(3) is available]],
+ [[mhd_cv_func_pthread_sigmask]], [dnl
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
+ [[
+ sigset_t nset, oset;
+ sigemptyset (&nset);
+ sigaddset (&nset, SIGPIPE);
+ if (0 != pthread_sigmask(SIG_BLOCK, &nset, &oset)) return 1;
+ ]])],
+ [[mhd_cv_func_pthread_sigmask="yes"]],[[mhd_cv_func_pthread_sigmask="no"]])
+ LIBS="${save_LIBS}"
+ CFLAGS="${save_CFLAGS}"
+ ])
+ AS_VAR_IF([mhd_cv_func_pthread_sigmask],["yes"],
+ [AC_DEFINE([[HAVE_PTHREAD_SIGMASK]],[[1]],[Define to 1 if you have the pthread_sigmask(3) function.])])
],[[mhd_have_posix_threads='no']])
AM_CONDITIONAL([HAVE_POSIX_THREADS],[test "x$mhd_have_posix_threads" = "xyes"])
@@ -366,7 +605,9 @@
[
AC_MSG_CHECKING([[for W32 threads]])
AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([#include <windows.h>], [ HANDLE h = CreateThread(NULL, 0, NULL, NULL, 0, NULL);])]
+ [AC_LANG_PROGRAM([[
+#include <windows.h>
+ ]], [ HANDLE h = CreateThread(NULL, 0, NULL, NULL, 0, NULL);])]
, [[mhd_have_w32_threads='yes']], [[mhd_have_w32_threads='no']]
)
AC_MSG_RESULT([[$mhd_have_w32_threads]])
@@ -374,48 +615,50 @@
]
)
-AC_MSG_CHECKING([[for threading lib to use with libmicrohttpd]])
-AS_IF([[test "x$with_threads" = "xposix"]],
+AC_MSG_CHECKING([[for threading lib to use with libmicrohttpd ($with_threads)]])
+AS_IF([test "x$with_threads" = "xposix"],
[ # forced posix threads
- AS_IF([[test "x$mhd_have_posix_threads" = "xyes"]], [[ USE_THREADS='posix' ]],
+ AS_IF([test "x$mhd_have_posix_threads" = "xyes"], [USE_THREADS='posix'],
[ AS_IF([[test "x$os_is_windows" = "xyes"]] ,
[ AC_MSG_ERROR([[Posix threads are not available. Try to configure --with-threads=auto]])],
[ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]])] )
])
- ] ,
- [[ test "x$with_threads" = "xw32" ]] ,
+ ])
+AS_IF([test "x$with_threads" = "xw32"],
[ # forced w32 threads
AS_IF([[test "x$mhd_have_w32_threads" = "xyes"]],
[[ USE_THREADS='w32' ]],
[ AC_MSG_ERROR([[W32 threads are not available. Try to configure --with-threads=auto]])])
- ] ,
- [ # automatic threads lib selection
- AS_IF([[test "x$os_is_native_w32" = "xyes" && test "x$mhd_have_w32_threads" = "xyes"]] ,
+ ])
+AS_IF([test "x$with_threads" = "xauto"],
+ [# automatic threads lib selection
+ AS_IF([[test "x$os_is_native_w32" = "xyes" && test "x$mhd_have_w32_threads" = "xyes"]] ,
[[ USE_THREADS='w32' ]] ,
[[ test "x$mhd_have_posix_threads" = "xyes" ]], [[ USE_THREADS='posix' ]],
[[ test "x$mhd_have_w32_threads" = "xyes" ]], [[ USE_THREADS='w32' ]],
[ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]]) ]
- )
- ]
- )
-if test "x$USE_THREADS" = "xposix"; then
- CC="$PTHREAD_CC"
+ )])
+AS_IF([test "x$with_threads" = "xnone"],
+ [USE_THREADS='none'])
+
+AS_IF([test "x$USE_THREADS" = "xposix"],
+ [CC="$PTHREAD_CC"
AC_DEFINE([MHD_USE_POSIX_THREADS],[1],[define to use pthreads])
MHD_LIB_CFLAGS="$MHD_LIB_CFLAGS $PTHREAD_CFLAGS"
MHD_LIBDEPS="$PTHREAD_LIBS $MHD_LIBDEPS"
- MHD_LIBDEPS_PKGCFG="$PTHREAD_LIBS $MHD_LIBDEPS_PKGCFG"
-elif test "x$USE_THREADS" = "xw32"; then
- AC_DEFINE([MHD_USE_W32_THREADS],[1],[define to use W32 threads])
-fi
+ MHD_LIBDEPS_PKGCFG="$PTHREAD_LIBS $MHD_LIBDEPS_PKGCFG"],
+ [AS_IF([test "x$USE_THREADS" = "xw32"],
+ [AC_DEFINE([MHD_USE_W32_THREADS],[1],[define to use W32 threads])])])
AM_CONDITIONAL([USE_POSIX_THREADS], [test "x$USE_THREADS" = "xposix"])
AM_CONDITIONAL([USE_W32_THREADS], [test "x$USE_THREADS" = "xw32"])
-AC_MSG_RESULT([[$USE_THREADS]])
+AM_CONDITIONAL([DISABLE_THREADS], [test "x$USE_THREADS" = "xnone"])
+AC_MSG_RESULT([$USE_THREADS])
AC_ARG_ENABLE([[thread-names]],
- [AS_HELP_STRING([--disable-thread-names [auto] ],[do not set names on MHD generated threads])],
+ [AS_HELP_STRING([--disable-thread-names],[do not set names on MHD generated threads [auto]])],
[], [enable_thread_names='auto'])
-if test "x$enable_thread_names" != "xno" && test "x$USE_THREADS" = "xposix"; then
+AS_IF([test "x$enable_thread_names" != "xno" && test "x$USE_THREADS" = "xposix"],[
# Check for thread name function
HAVE_THREAD_NAME_FUNC="no"
SAVE_LIBS="$LIBS"
@@ -482,7 +725,7 @@
)
])
- # Try to find how to set thread name for started thread - less convinent
+ # Try to find how to set thread name for started thread - less convenient
# than setting name by attributes.
# If pthread_setname_np(3) is not declared, it's not possible to detect
# form of pthread_setname_np(3) due to C "feature" "implicit declaration".
@@ -571,10 +814,9 @@
LIBS="$SAVE_LIBS"
CFLAGS="$SAVE_CFLAGS"
-fi
+])
-AS_IF(
- [[test "x$enable_thread_names" != "xno"]],
+AS_IF([[test "x$enable_thread_names" != "xno"]],
[
AC_MSG_CHECKING([[whether to enable thread names]])
AC_COMPILE_IFELSE(
@@ -628,6 +870,11 @@
MHD_CHECK_SOCKET_SHUTDOWN_TRIGGER([AC_DEFINE([HAVE_LISTEN_SHUTDOWN],[1],[can use shutdown on listen sockets])])
AM_CONDITIONAL([HAVE_LISTEN_SHUTDOWN], [test "x$mhd_cv_host_shtdwn_trgr_select" = "xyes"])
+# SENDMSG. Should we check for SCM_RIGHTS instead?
+# https://lists.x.org/archives/xorg-devel/2013-November/038687.html
+AC_SEARCH_LIBS([sendmsg], [socket], [AC_DEFINE([HAVE_SENDMSG],[1],[Define if your platform supports sendmsg])])
+AC_CHECK_FUNCS([writev])
+
# set GCC options
# use '-fno-strict-aliasing', but only if the compiler
# and linker can take it
@@ -635,6 +882,38 @@
[AX_APPEND_COMPILE_FLAGS([-fno-strict-aliasing])])
AC_C_BIGENDIAN
+AC_C_VARARRAYS
+
+AC_CACHE_CHECK([[whether __func__ magic-macro is available]],
+ [[mhd_cv_macro___func___avail]], [dnl
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>]],[[const char *funcname = __func__ ; if (NULL == funcname) return 1;]])],
+ [[mhd_cv_macro___func___avail="yes"]],[[mhd_cv_macro___func___avail="no"]])
+])
+AS_VAR_IF([mhd_cv_macro___func___avail], ["yes"],
+ [AC_DEFINE([HAVE___FUNC__], [1], [Define to 1 if your compiler supports __func__ magic-macro.])],
+ [
+ AC_CACHE_CHECK([[whether __FUNCTION__ magic-macro is available]],
+ [[mhd_cv_macro___function___avail]], [dnl
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>]],[[const char *funcname = __FUNCTION__ ; if (NULL == funcname) return 1;]])],
+ [[mhd_cv_macro___function___avail="yes"]],[[mhd_cv_macro___function___avail="no"]])
+ ])
+ AC_DEFINE([HAVE___FUNCTION__], [1], [Define to 1 if your compiler supports __FUNCTION__ magic-macro.])
+ ]
+)
+AC_CACHE_CHECK([[whether __builtin_bswap32() is available]],
+ [[mhd_cv_func___builtin_bswap32_avail]], [dnl
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include<stdint.h>]], [[uint32_t a = 1; uint32_t b = __builtin_bswap32(a); a = b;]])],
+ [[mhd_cv_func___builtin_bswap32_avail="yes"]],[[mhd_cv_func___builtin_bswap32_avail="no"]])
+])
+AS_IF([[test "x$mhd_cv_func___builtin_bswap32_avail" = "xyes"]],
+ [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP32]], [[1]], [Define to 1 if you have __builtin_bswap32() builtin function])])
+AC_CACHE_CHECK([[whether __builtin_bswap64() is available]],
+ [[mhd_cv_func___builtin_bswap64_avail]], [dnl
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include<stdint.h>]], [[uint64_t a = 1; uint32_t b = __builtin_bswap64(a); a = b;]])],
+ [[mhd_cv_func___builtin_bswap64_avail="yes"]], [[mhd_cv_func___builtin_bswap64_avail="no"]])
+])
+AS_IF([[test "x$mhd_cv_func___builtin_bswap64_avail" = "xyes"]],
+ [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP64]], [[1]], [Define to 1 if you have __builtin_bswap64() builtin function])])
AC_CHECK_PROG([HAVE_CURL_BINARY],[curl],[yes],[no])
AM_CONDITIONAL([HAVE_CURL_BINARY],[test "x$HAVE_CURL_BINARY" = "xyes"])
@@ -655,35 +934,39 @@
test "x$enable_examples" = "xno" || enable_examples=yes
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$enable_examples" = "xyes"])
+AC_ARG_ENABLE([[heavy-tests]],
+ [AS_HELP_STRING([[--enable-heavy-tests]], [use heavy tests in test-suite. WARNING:]
+ [a dedicated host with minimal number of background processes and no network]
+ [activity is recommended to enable.])], [],
+ [enable_heavy_tests=no])
+AS_VAR_IF([enable_heavy_tests], ["yes"], [], [enable_heavy_tests=no])
+AM_CONDITIONAL([HEAVY_TESTS],[test "x$enable_heavy_tests" = "xyes"])
+
AC_ARG_ENABLE([[poll]],
[AS_HELP_STRING([[--enable-poll[=ARG]]], [enable poll support (yes, no, auto) [auto]])],
[enable_poll=${enableval}],
[enable_poll='auto']
)
-if test "$enable_poll" != "no"; then
- if test "$os_is_native_w32" != "yes"; then
- AC_CHECK_HEADERS([poll.h],
- [
- AC_CHECK_FUNCS([poll], [have_poll='yes'], [have_poll='no'])
- ], [], [AC_INCLUDES_DEFAULT])
- else
- AC_MSG_CHECKING([for WSAPoll()])
- AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[#include <winsock2.h>]], [[
+AS_IF([test "$enable_poll" != "no"],
+ [AS_IF([test "$os_is_native_w32" != "yes"],
+ AC_CHECK_HEADERS([poll.h],
+ [AC_CHECK_FUNCS([poll], [have_poll='yes'], [have_poll='no'])],
+ [],
+ [AC_INCLUDES_DEFAULT]),
+ [AC_MSG_CHECKING([for WSAPoll()])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <winsock2.h>
+ ]],[[
WSAPOLLFD fda[2];
WSAPoll(fda, 2, 0);]])],
- [
- have_poll='yes'
- AC_DEFINE([HAVE_POLL],[1])
- ], [have_poll='no'])
- AC_MSG_RESULT([$have_poll])
- fi
- if test "$enable_poll" = "yes" && test "$have_poll" != "yes"; then
- AC_MSG_ERROR([[Support for poll was explicitly requested but cannot be enabled on this platform.]])
- fi
- enable_poll="$have_poll"
-fi
+ [have_poll='yes'
+ AC_DEFINE([HAVE_POLL],[1])
+ ],[have_poll='no'])
+ AC_MSG_RESULT([$have_poll])])
+ AS_IF([test "$enable_poll" = "yes" && test "$have_poll" != "yes"],
+ AC_MSG_ERROR([[Support for poll was explicitly requested but cannot be enabled on this platform.]]))
+ enable_poll="$have_poll"])
AC_ARG_ENABLE([[epoll]],
[AS_HELP_STRING([[--enable-epoll[=ARG]]], [enable epoll support (yes, no, auto) [auto]])],
@@ -691,38 +974,39 @@
[enable_epoll='auto']
)
-if test "$enable_epoll" != "no"; then
- AX_HAVE_EPOLL
- if test "${ax_cv_have_epoll}" = "yes"; then
- AC_DEFINE([[EPOLL_SUPPORT]],[[1]],[Define to 1 to enable epoll support])
- enable_epoll='yes'
- else
- if test "$enable_epoll" = "yes"; then
- AC_MSG_ERROR([[Support for epoll was explicitly requested but cannot be enabled on this platform.]])
- fi
- enable_epoll='no'
- fi
-fi
-
-if test "x$enable_epoll" = "xyes"; then
- AC_CACHE_CHECK([for epoll_create1()], [mhd_cv_have_epoll_create1], [
+AS_IF([test "$enable_epoll" != "no"],
+ [AX_HAVE_EPOLL
+ AS_IF([test "${ax_cv_have_epoll}" = "yes"],
+ [AC_DEFINE([[EPOLL_SUPPORT]],[[1]],[Define to 1 to enable epoll support])
+ enable_epoll='yes'],
+ [AS_IF([test "$enable_epoll" = "yes"],
+ AC_MSG_ERROR([[Support for epoll was explicitly requested but cannot be enabled on this platform.]]))
+ enable_epoll='no'])])
+
+AM_CONDITIONAL([MHD_HAVE_EPOLL], [[test "x$enable_epoll" = xyes]])
+
+AS_IF([test "x$enable_epoll" = "xyes"],
+ AC_CACHE_CHECK([for epoll_create1()],
+ [mhd_cv_have_epoll_create1], [
AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[#include <sys/epoll.h>]], [[
+ AC_LANG_PROGRAM([[
+#include <sys/epoll.h>
+ ]], [[
int fd;
fd = epoll_create1(EPOLL_CLOEXEC);]])],
[mhd_cv_have_epoll_create1=yes],
[mhd_cv_have_epoll_create1=no])])
AS_IF([test "x$mhd_cv_have_epoll_create1" = "xyes"],[
- AC_DEFINE([[HAVE_EPOLL_CREATE1]], [[1]], [Define if you have epoll_create1 function.])])
-fi
+ AC_DEFINE([[HAVE_EPOLL_CREATE1]], [[1]], [Define if you have epoll_create1 function.])]))
# Check for headers that are ALWAYS required
-AC_CHECK_HEADERS([fcntl.h math.h errno.h limits.h stdio.h locale.h sys/stat.h sys/types.h], [], [AC_MSG_ERROR([Compiling libmicrohttpd requires standard UNIX headers files])], [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS_ONCE([fcntl.h math.h errno.h limits.h stdio.h locale.h sys/stat.h sys/types.h], [], [AC_MSG_ERROR([Compiling libmicrohttpd requires standard UNIX headers files])], [AC_INCLUDES_DEFAULT])
# Check for optional headers
AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h time.h sys/mman.h sys/ioctl.h \
sys/socket.h sys/select.h netdb.h netinet/in.h netinet/ip.h netinet/tcp.h arpa/inet.h \
endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h \
+ signal.h \
inttypes.h stddef.h unistd.h \
sockLib.h inetLib.h net/if.h], [], [], [AC_INCLUDES_DEFAULT])
@@ -737,13 +1021,34 @@
AM_CONDITIONAL([MHD_HAVE_TSEARCH], [[test "x$ac_cv_header_search_h" = xyes && test "x$HAVE_TSEARCH" = "x1" && test "x$REPLACE_TSEARCH" != "x1"]])
+AC_CHECK_HEADERS([dlfcn.h],[have_tlsplugin=yes],[have_tlsplugin=no], [AC_INCLUDES_DEFAULT])
+AM_CONDITIONAL([MHD_HAVE_TLS_PLUGIN], [[test "x$have_tlsplugin" = xyes]])
+
+AC_CHECK_HEADERS([zlib.h],[have_zlib=yes],[have_zlib=no], [AC_INCLUDES_DEFAULT])
+AM_CONDITIONAL([HAVE_ZLIB], [[test "x$have_zlib" = xyes]])
+
# Check for generic functions
-AC_CHECK_FUNCS([rand random])
+MHD_CHECK_FUNC([random],
+ [
+AC_INCLUDES_DEFAULT
+[#include <stdlib.h>
+ ]],
+ [[long int r = random(); (void)r;]],
+ [],
+ [
+ MHD_CHECK_FUNC([rand],
+ [
+AC_INCLUDES_DEFAULT
+[#include <stdlib.h>
+ ]],
+ [[int r = rand(); (void)r;]],
+ )
+ ]
+)
-AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
- [ AC_DEFINE(HAVE_SOCKADDR_IN_SIN_LEN, 1, [Do we have sockaddr_in.sin_len?])
- ],
- [],
+AC_CHECK_MEMBERS([struct sockaddr_in.sin_len, struct sockaddr_in6.sin6_len,
+ struct sockaddr_storage.ss_len],
+ [], [],
[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -756,6 +1061,122 @@
#endif
])
+MHD_CHECK_FUNC([getsockname],
+ [[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+ ]],
+ [
+ struct sockaddr_storage ss;
+ (void)getsockname(socket(0,0,0),(struct sockaddr *)&ss,(void*)0);
+ ],
+ [
+ AC_CACHE_CHECK([[whether getsockname() is usable]], [[mhc_cv_getsockname_usable]],
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+
+static void zr_mem(void *ptr, socklen_t size)
+{ char *mem = ptr; while(size--) {mem[0] = 0; mem++;} }
+
+int main(void)
+{
+ const socklen_t c_addr_size = (socklen_t)sizeof(struct sockaddr_in);
+ struct sockaddr_in sa;
+ socklen_t addr_size;
+ int ret = 1;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ int sckt;
+ const int invld_sckt = -1;
+#else
+ SOCKET sckt;
+ const SOCKET invld_sckt = INVALID_SOCKET;
+ WSADATA wsa_data;
+
+ if (0 != WSAStartup(MAKEWORD(2, 2), &wsa_data) || MAKEWORD(2, 2) != wsa_data.wVersion)
+ return 20;
+#endif
+
+ sckt = socket (PF_INET, SOCK_STREAM, 0);
+ if (invld_sckt != sckt)
+ {
+ zr_mem(&sa, c_addr_size);
+ sa.sin_family = AF_INET;
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sa.sin_len = c_addr_size;
+#endif
+ if (0 == bind (sckt, (struct sockaddr *)&sa, c_addr_size))
+ {
+ if (0 == listen (sckt, 1))
+ {
+ addr_size = c_addr_size;
+ if (0 == getsockname (sckt, (struct sockaddr *)&sa, &addr_size))
+ {
+ if (c_addr_size >= addr_size)
+ {
+ if (0 != ntohs(sa.sin_port))
+ { ret = 0;
+ } else ret = 7;
+ } else ret = 6;
+ } else ret = 5;
+ } else ret = 4;
+ } else ret = 3;
+ } else ret = 2;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ close (sckt);
+#else
+ closesocket (sckt);
+ WSACleanup();
+#endif
+ return ret;
+}
+ ]]
+ )
+ ],
+ [[mhc_cv_getsockname_usable='yes']],
+ [[mhc_cv_getsockname_usable='no']],
+ [[mhc_cv_getsockname_usable='assuming yes']]
+ )
+ ]
+ )
+ AS_VAR_IF([[mhc_cv_getsockname_usable]], [["no"]], [:],
+ [AC_DEFINE([[MHD_USE_GETSOCKNAME]], [[1]], [Define if you have usable `getsockname' function.])])
+ ]
+)
# Check for inter-thread signaling type
AC_ARG_ENABLE([[itc]],
@@ -777,7 +1198,7 @@
AS_IF([[test "x$enable_itc" = "xeventfd" || test "x$enable_itc" = "xauto"]], [
AS_VAR_IF([[os_is_native_w32]], [["yes"]], [], [
- AC_CHECK_HEADERS([[sys/eventfd.h]], [], [], [AC_INCLUDES_DEFAULT])
+ AC_CHECK_HEADERS([sys/eventfd.h], [], [], [AC_INCLUDES_DEFAULT])
AS_VAR_IF([[ac_cv_header_sys_eventfd_h]], [["yes"]], [
AC_CACHE_CHECK([whether eventfd(2) is usable], [[mhd_cv_eventfd_usable]], [
AC_LINK_IFELSE([
@@ -880,7 +1301,7 @@
])
])
-AS_IF([[test -z "$use_itc"]], [AC_MSG_ERROR([[cannot find useable type of inter-thread communication]])])
+AS_IF([[test -z "$use_itc"]], [AC_MSG_ERROR([[cannot find usable type of inter-thread communication]])])
AC_CHECK_FUNCS_ONCE([accept4 gmtime_r memmem snprintf])
@@ -961,7 +1382,9 @@
])
], [], [$MHD_LIBDEPS])
LIBS="$SAVE_LIBS"
- ], [], [[#include <time.h>]])
+ ], [], [[
+#include <time.h>
+ ]])
AC_MSG_CHECKING([[for clock_get_time]])
AC_LINK_IFELSE(
@@ -1035,23 +1458,23 @@
])
AC_MSG_RESULT($have_inet6)
+MHD_CHECK_FUNC([[sysconf]], [[#include <unistd.h>]], [[long a = sysconf(0); if (a) return 1;]])
+
HIDDEN_VISIBILITY_CFLAGS=""
-case "$host" in
- *-*-mingw*)
+AS_CASE(["$host"],
+ [*-*-mingw*],[
dnl on mingw32 we do -fvisibility=hidden and __declspec(dllexport)
AC_DEFINE([_MHD_EXTERN], [__attribute__((visibility("default"))) __declspec(dllexport) extern],
[defines how to decorate public symbols while building])
HIDDEN_VISIBILITY_CFLAGS="-fvisibility=hidden"
- ;;
- *)
+ ],[
dnl on other compilers, check if we can do -fvisibility=hidden
AX_CHECK_LINK_FLAG([-fvisibility=hidden],
[AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],
[AC_DEFINE([_MHD_EXTERN], [__attribute__((visibility("default"))) extern],
[defines how to decorate public symbols while building])
HIDDEN_VISIBILITY_CFLAGS="-fvisibility=hidden"])])
- ;;
-esac
+ ])
AC_SUBST(HIDDEN_VISIBILITY_CFLAGS)
# libcurl (required for testing)
@@ -1059,37 +1482,240 @@
[AS_HELP_STRING([--disable-curl],[disable cURL based testcases])],
[enable_curl=${enableval}])
curl=0
-if test "$enable_curl" != "no"
-then
- LIBCURL_CHECK_CONFIG([yes],[7.16.4],[enable_curl=yes],
+AS_IF([test "$enable_curl" != "no"],
+ [LIBCURL_CHECK_CONFIG([yes],[7.16.4],[enable_curl=yes],
[
- if test "x$enable_curl" = "xyes"; then
- AC_MSG_WARN([[cURL-based tests cannot be enabled because libcurl is missing]])
- fi
+ AS_IF([test "x$enable_curl" = "xyes"],
+ [AC_MSG_WARN([[cURL-based tests cannot be enabled because libcurl is missing]])])
enable_curl=no
])
-fi
-if test "$enable_curl" != "no"
-then
+])
+AS_IF([test "$enable_curl" != "no"],
+ [
# Lib cURL & cURL - OpenSSL versions
AC_DEFINE([MHD_REQ_CURL_VERSION], ["7.16.4"], [required cURL version to run tests])
AC_DEFINE([MHD_REQ_CURL_OPENSSL_VERSION], ["0.9.8"], [required cURL SSL version to run tests])
AC_DEFINE([MHD_REQ_CURL_GNUTLS_VERSION], ["2.8.6"], [gnuTLS lib version - used in conjunction with cURL])
AC_DEFINE([MHD_REQ_CURL_NSS_VERSION], ["3.12.0"], [NSS lib version - used in conjunction with cURL])
-fi
+ ])
AM_CONDITIONAL([HAVE_CURL], [test "x$enable_curl" = "xyes"])
-mhd_have_magic_open='no'
-AC_CHECK_HEADERS([[magic.h]],
- [ AC_CHECK_LIB([[magic]], [[magic_open]], [[mhd_have_magic_open='yes']]) ],[],
- [AC_INCLUDES_DEFAULT])
-
-AM_CONDITIONAL([HAVE_MAGIC], [[test "x$mhd_have_magic_open" = "xyes"]])
+mhd_have_libmagic="no"
+SAVE_LIBS="$LIBS"
+LIBS="$LIBS -lmagic"
+AC_MSG_CHECKING([[for suitable libmagic]])
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <magic.h>
+ ]],
+ [[
+ char var_data[256];
+ const char *var_mime;
+ magic_t var_magic = magic_open (MAGIC_MIME_TYPE);
+ (void)magic_load (var_magic, NULL);
+ var_data[0] = 0;
+ var_mime = magic_buffer (var_magic, var_data, 1);
+ magic_close (var_magic);
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_LIBMAGIC], [1], [Define to 1 if you have suitable libmagic.])
+ mhd_have_libmagic="yes"
+ AC_MSG_RESULT([[yes]])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+)
+LIBS="$SAVE_LIBS"
+AM_CONDITIONAL([HAVE_LIBMAGIC], [[test "x$mhd_have_libmagic" = "xyes"]])
# large file support (> 4 GB)
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
-AC_CHECK_FUNCS([lseek64 sendfile64 pread64 pread])
+AC_CHECK_FUNCS([lseek64 pread64 pread])
+
+# check for various sendfile functions
+AC_ARG_ENABLE([sendfile],
+ [AS_HELP_STRING([--disable-sendfile],
+ [disable usage of sendfile() for HTTP connections [auto]])],
+ [],
+ [enable_sendfile="auto"])
+AS_CASE([$enable_sendfile],
+ [[auto | yes]],[[found_sendfile="no"]],
+ [[no]],[[found_sendfile="disabled"]],
+ [AC_MSG_ERROR([[unknown value specified: --enable-sendfile=$enable_sendfile]])]
+)
+AS_VAR_IF([[found_sendfile]], [["no"]],
+ [
+ AC_MSG_CHECKING([[for Linux-style sendfile(2)]])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <sys/sendfile.h>
+
+static void empty_func(void)
+{
+/* Check for declaration */
+ (void)sendfile;
+}
+/* Declare again to check form match */
+ssize_t sendfile(int, int, off_t*, size_t);
+ ]],
+ [[
+ int fd1=0, fd2=2;
+ off_t o = 0;
+ size_t s = 5;
+ ssize_t r;
+ r = sendfile (fd1, fd2, &o, s);
+ if (r)
+ empty_func();
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_LINUX_SENDFILE], [1], [Define to 1 if you have linux-style sendfile(2).])
+ found_sendfile="yes, Linux-style"
+ AC_MSG_RESULT([[yes]])
+ AC_CHECK_FUNCS([sendfile64])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+ )
+ ]
+)
+AS_VAR_IF([[found_sendfile]], [["no"]],
+ [
+ AC_MSG_CHECKING([[for FreeBSD-style sendfile(2)]])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+static void empty_func(void)
+{
+/* Check for declaration */
+ (void)sendfile;
+}
+/* Declare again to check form match */
+int sendfile(int, int, off_t, size_t,
+ struct sf_hdtr*, off_t*, int);
+ ]],
+ [[
+ int fd1=0, fd2=1;
+ off_t o = 0;
+ size_t s = 5;
+ off_t r1;
+ int r2;
+ r2 = sendfile (fd1, fd2, o, s, (void*)0, &r1, 0);
+ if (r2)
+ empty_func();
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_FREEBSD_SENDFILE], [1], [Define to 1 if you have FreeBSD-style sendfile(2).])
+ found_sendfile="yes, FreeBSD-style"
+ AC_MSG_RESULT([[yes]])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+ )
+ ]
+)
+AS_VAR_IF([[found_sendfile]], [["no"]],
+ [
+ AC_MSG_CHECKING([[for Darwin-style sendfile(2)]])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+static void empty_func(void)
+{
+/* Check for declaration */
+ (void)sendfile;
+}
+/* Declare again to check form match */
+int sendfile(int, int, off_t, off_t*,
+ struct sf_hdtr *, int);
+ ]],
+ [[
+ int fd=0, s=1;
+ off_t o = 0;
+ off_t l = 5;
+ int r;
+ r = sendfile (fd, s, o, &l, (void*)0, 0);
+ if (r)
+ empty_func();
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_DARWIN_SENDFILE], [1], [Define to 1 if you have Darwin-style sendfile(2).])
+ found_sendfile="yes, Darwin-style"
+ AC_MSG_RESULT([[yes]])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+ )
+ ]
+)
+
+AS_VAR_IF([[found_sendfile]], [["no"]],
+ [
+ AC_MSG_CHECKING([[for Solaris-style sendfile(3)]])
+ SAVE_LIBS="$LIBS"
+ LIBS="$LIBS -lsendfile"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sendfile.h>
+
+static void empty_func(void)
+{
+/* Check for declaration */
+ (void)sendfile;
+}
+/* Declare again to check form match */
+ssize_t sendfile(int out_fd, int in_fd,
+ off_t *off, size_t len);
+ ]],
+ [[
+ int fd1=0, fd2=1;
+ off_t o = 0;
+ size_t l = 5;
+ ssize_t r;
+ r = sendfile (fd1, fd2, &o, l);
+ if (r)
+ empty_func();
+ ]]
+ )
+ ],
+ [
+ AC_DEFINE([HAVE_SOLARIS_SENDFILE], [1], [Define to 1 if you have Solaris-style sendfile(3).])
+ found_sendfile="yes, Solaris-style"
+ MHD_LIBDEPS="-lsendfile $MHD_LIBDEPS"
+ MHD_LIBDEPS_PKGCFG="-lsendfile $MHD_LIBDEPS_PKGCFG"
+ AC_MSG_RESULT([[yes]])
+ AC_CHECK_FUNCS([sendfile64])
+ ],
+ [AC_MSG_RESULT([[no]])
+ ]
+ )
+ LIBS="$SAVE_LIBS"
+ ]
+)
+AS_IF([[test "x$found_sendfile" = "xno" && test "x$enable_sendfile" = "xyes"]],
+ [AC_MSG_ERROR([[sendfile() usage was requested by configure parameter, but no usable sendfile() function is detected]])]
+)
# optional: have error messages ?
AC_MSG_CHECKING([[whether to generate error messages]])
@@ -1124,54 +1750,45 @@
AM_CONDITIONAL([HAVE_ZZUF], [test "x$have_zzuf" = "xyes"])
AM_CONDITIONAL([HAVE_SOCAT], [test "x$have_socat" = "xyes"])
-GNUTLS_CPPFLAGS=""
-GNUTLS_LDFLAGS=""
have_gnutls=no
have_gnutls_sni=no
have_gcrypt=no
+AS_UNSET([GNUTLS_CPPFLAGS])
+AS_UNSET([GNUTLS_LDFLAGS])
# optional: HTTPS support. Enabled by default
AC_ARG_ENABLE([https],
[AS_HELP_STRING([--enable-https],
[enable HTTPS support (yes, no, auto)[auto]])],
[enable_https=${enableval}])
-if test "x$enable_https" != "xno"
-then
+AS_IF([test "x$enable_https" != "xno"],[
#
# Next block is large unindented block
#
-# libgcrypt linkage: required for HTTPS support
-AM_PATH_LIBGCRYPT([1.2.2], [have_gcrypt=yes], [have_gcrypt=no])
-if test "x$have_gcrypt" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
- # LIBGCRYPT_CFLAGS can be actually a CPPFLAGS, so check them both
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $LIBGCRYPT_CFLAGS"
- AC_CHECK_HEADERS([gcrypt.h], [], [have_gcrypt=no], [AC_INCLUDES_DEFAULT])
- CFLAGS="$SAVE_CFLAGS"
- CPPFLAGS="$SAVE_CPPFLAGS"
-fi
-
# gnutls
have_gnutls_pkgcfg=no
AC_MSG_CHECKING([[how to find GnuTLS library]])
AC_ARG_WITH([[gnutls]],
[AS_HELP_STRING([[--with-gnutls[=PFX]]],[use GnuTLS for HTTPS support, optional PFX overrides pkg-config data for GnuTLS headers (PFX/include) and libs (PFX/lib)])],
[
- case $with_gnutls in
- no)
+ AS_CASE([$with_gnutls],
+ [no],[
AC_MSG_RESULT([[GnuTLS disabled]])
- ;;
- yes)
+ AS_UNSET([GNUTLS_CPPFLAGS])
+ AS_UNSET([GNUTLS_CFLAGS])
+ AS_UNSET([GNUTLS_LDFLAGS])
+ AS_UNSET([GNUTLS_LIBS])
+ ],
+ [yes],[
AC_MSG_RESULT([[automatically, forced]])
- ;;
- *)
+ ],
+ [
AC_MSG_RESULT([[-I$with_gnutls/include -L$with_gnutls/lib -lgnutls]])
SAVE_LDFLAGS="$LDFLAGS"
SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_CFLAGS="$CFLAGS"
+ SAVE_LIBS="$LIBS"
LDFLAGS="-L$with_gnutls/lib $LDFLAGS"
CPPFLAGS="-I$with_gnutls/include $CPPFLAGS"
have_gnutls_pkgcfg=no
@@ -1181,20 +1798,61 @@
GNUTLS_CPPFLAGS="-I$with_gnutls/include"
GNUTLS_LDFLAGS="-L$with_gnutls/lib"
GNUTLS_LIBS="-lgnutls"
- AC_CHECK_LIB([gnutls], [gnutls_load_file], [AC_CHECK_LIB([gnutls], [gnutls_privkey_import_x509_raw], [have_gnutls_sni=yes])])
have_gnutls=yes
])], [], [AC_INCLUDES_DEFAULT])
AS_IF([test "x$have_gnutls" != "xyes"], [AC_MSG_ERROR([can't find usable libgnutls at specified prefix $with_gnutls])])
- LDFLAGS="$SAVE_LDFLAGS"
CPPFLAGS="$SAVE_CPPFLAGS"
- ;;
- esac
+ CFLAGS="$SAVE_CFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+ LIBS="$SAVE_LIBS"
+ ])
],
[AC_MSG_RESULT([[automatically]])
])
AS_IF([test "x$with_gnutls" != "xno" && test "x$have_gnutls" != "xyes"],
[
+ AC_CACHE_CHECK([[whether to add pkg-config special search directories]], [mhd_cv_pkgconf_add_dirs],
+ [
+ AS_IF([[test "x$host_os" = "xsolaris2.11" && test "x$cross_compiling" = "xno"]],
+ [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+char size_chk[7-sizeof(char*)];
+#if defined(_LP64) || defined(__LP64__) || defined(__x86_64) || defined(__x86_64__)
+#error This is 64-bit target.
+choke me now
+#endif
+#if defined(__amd64) || defined(__amd64__) || defined(__sparcv9) || defined(__sparc_v9__)
+#error This is 64-bit target.
+choke me now
+#endif
+ ]], [[]]
+ )
+ ],
+ [
+ mhd_cv_pkgconf_add_dirs='/usr/lib/pkgconfig/gnutls-3'
+ ],
+ [
+ AS_IF([[test "x$host_cpu" = "xx86_64" || test "x$host_cpu" = "xi386"]],
+ [[mhd_cv_pkgconf_add_dirs='/usr/lib/amd64/pkgconfig/gnutls-3:/usr/lib/amd64/pkgconfig']],
+ [[test "x$host_cpu" = "xsparc"]],
+ [[mhd_cv_pkgconf_add_dirs='/usr/lib/sparkv9/pkgconfig/gnutls-3:/usr/lib/sparkv9/pkgconfig']],
+ [[mhd_cv_pkgconf_add_dirs='/usr/lib/64/pkgconfig/gnutls-3:/usr/lib/64/pkgconfig']]
+ )
+ ]
+ )
+ ],
+ [[ mhd_cv_pkgconf_add_dirs='no' ]]
+ )
+ ]
+ )
+ AS_IF([[test "x$mhd_cv_pkgconf_add_dirs" != "xno"]],
+ [
+ test "x$PKG_CONFIG_PATH" = "x" || PKG_CONFIG_PATH="${PKG_CONFIG_PATH}${PATH_SEPARATOR}"
+ PKG_CONFIG_PATH="${PKG_CONFIG_PATH}${mhd_cv_pkgconf_add_dirs}"
+ export PKG_CONFIG_PATH
+ ]
+ )
PKG_CHECK_MODULES(GNUTLS, [[gnutls]],
[
have_gnutls_pkgcfg='yes'
@@ -1202,13 +1860,13 @@
SAVE_CFLAGS="$CFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
SAVE_LIBS="$LIBS"
- CPPFLAGS="$GNUTLS_CFLAGS $CPPFLAGS"
CFLAGS="$GNUTLS_CFLAGS $CFLAGS"
- LDFLAGS="$GNUTLS_LIBS $LDFLAGS"
LIBS="$LIBS $GNUTLS_LIBS"
AC_MSG_CHECKING([[whether GnuTLS is usable]])
AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], [[
+ AC_LANG_PROGRAM([[
+#include <gnutls/gnutls.h>
+ ]], [[
gnutls_session_t session;
gnutls_priority_t priorities;
gnutls_global_init();
@@ -1219,103 +1877,247 @@
[
AC_MSG_RESULT([[yes]])
have_gnutls=yes
+ # GNUTLS_CFLAGS is actually CPPFLAGS
GNUTLS_CPPFLAGS="$GNUTLS_CFLAGS"
+ # GNUTLS_CFLAGS is combination of LDFLAGS and LIBS
GNUTLS_LDFLAGS="$GNUTLS_LIBS"
- AC_MSG_CHECKING([[for gnutls_privkey_import_x509_raw()]])
- AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], [[
- gnutls_datum_t data;
- gnutls_privkey_t key;
- gnutls_load_file("key.pem", &data);
- gnutls_privkey_import_x509_raw(key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
- gnutls_free(data.data);
- ]])], [[have_gnutls_sni=yes]], [[have_gnutls_sni=no]])
- AC_MSG_RESULT([[$have_gnutls_sni]])
],
[
AC_MSG_RESULT([[no]])
have_gnutls=no
])
- AS_IF([test "x$have_gnutls" != "xyes"], [AC_MSG_WARN([pkg-config reports that GnuTLS is present, but GnuTLS can't be used])])
+ AS_IF([test "x$have_gnutls" != "xyes"],
+ [
+ AC_MSG_WARN([pkg-config reports that GnuTLS is present, but GnuTLS can't be used])
+ AS_UNSET([GNUTLS_CPPFLAGS])
+ AS_UNSET([GNUTLS_CFLAGS])
+ AS_UNSET([GNUTLS_LDFLAGS])
+ AS_UNSET([GNUTLS_LIBS])
+ ]
+ )
CPPFLAGS="$SAVE_CPPFLAGS"
CFLAGS="$SAVE_CFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
LIBS="$SAVE_LIBS"
],
[
+ # check for GnuTLS at default paths
have_gnutls_pkgcfg='no'
+ AC_CHECK_HEADERS([gnutls/gnutls.h],
+ [AC_CHECK_LIB([gnutls], [gnutls_priority_set],
+ [
+ GNUTLS_LIBS="-lgnutls"
+ have_gnutls=yes
+ ])], [], [AC_INCLUDES_DEFAULT])
+ ])
+ ])
+
+have_gcrypt='unknown'
+AS_IF([test "x$with_gnutls" != "xno" && test "x$have_gnutls" != "xyes"],
+ [
+ AM_PATH_LIBGCRYPT([1.2.2], [have_gcrypt=yes], [have_gcrypt=no])
+ AS_IF([[test "x$have_gcrypt" = "xyes"]],
+ [
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_CFLAGS="$CFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
SAVE_LIBS="$LIBS"
- # Try to use libgcrypt search path
- # as libgcrypt flags will be used
- # anyway for HTTPs builds
+ SAVE_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
+ # LIBGCRYPT_CFLAGS can be actually a CPPFLAGS, so check them both
CPPFLAGS="$CPPFLAGS $LIBGCRYPT_CFLAGS"
+ AC_CHECK_HEADERS([gcrypt.h], [], [have_gcrypt=no], [AC_INCLUDES_DEFAULT])
+ # Check for GnuTLS with gcrypt flags
LDFLAGS="$LDFLAGS $LIBGCRYPT_LIBS"
+ # A bit of hack: unset cache variable to force recheck
+ AS_UNSET([ac_cv_header_gnutls_gnutls_h])
AC_CHECK_HEADERS([gnutls/gnutls.h],
- [AC_CHECK_LIB([gnutls], [gnutls_priority_set],
+ [AS_UNSET([ac_cv_lib_gnutls_gnutls_priority_set]) # A bit of hack: unset cache variable to force recheck
+ AC_CHECK_LIB([gnutls], [gnutls_priority_set],
[
GNUTLS_CPPFLAGS="$LIBGCRYPT_CFLAGS"
GNUTLS_CFLAGS="$LIBGCRYPT_CFLAGS"
GNUTLS_LDFLAGS="$LIBGCRYPT_LIBS"
GNUTLS_LIBS="-lgnutls"
- AC_CHECK_LIB([gnutls], [gnutls_load_file], [AC_CHECK_LIB([gnutls], [gnutls_privkey_import_x509_raw], [have_gnutls_sni=yes])])
have_gnutls=yes
])], [], [AC_INCLUDES_DEFAULT])
CPPFLAGS="$SAVE_CPPFLAGS"
CFLAGS="$SAVE_CFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
LIBS="$SAVE_LIBS"
- ])
- ])
+ ]
+ )
+ ]
+)
+AS_IF([test "x$have_gnutls" != "xyes" && test "x$with_gnutls" = "xyes"],
+ [AC_MSG_ERROR([[can't find usable libgnutls]])])
-AS_IF([test "x$have_gnutls" != "xyes" && test "x$with_gnutls" = "xyes"], [AC_MSG_ERROR([[can't find usable libgnutls]])])
+ AS_IF([test "x$have_gnutls" = "xyes"],
+ [
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_CFLAGS="$CFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ SAVE_LIBS="$LIBS"
+ CPPFLAGS="$GNUTLS_CPPFLAGS $CPPFLAGS"
+ CFLAGS="$GNUTLS_CFLAGS $CFLAGS"
+ LDFLAGS="$GNUTLS_LDFLAGS $LDFLAGS"
+ LIBS="$LIBS $GNUTLS_LIBS"
+ AC_MSG_CHECKING([[for gnutls_privkey_import_x509_raw()]])
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+ ]], [[
+ gnutls_datum_t data;
+ gnutls_privkey_t key = 0;
+#ifndef gnutls_load_file
+ (void)gnutls_load_file; /* Check for declaration. */
+#endif
+#ifndef gnutls_privkey_import_x509_raw
+ (void)gnutls_privkey_import_x509_raw; /* Check for declaration. */
+#endif
+ gnutls_load_file("key.pem", &data);
+ gnutls_privkey_import_x509_raw(key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
+ gnutls_free(data.data);
+ ]])], [[have_gnutls_sni=yes]], [[have_gnutls_sni=no]])
+ AC_MSG_RESULT([[$have_gnutls_sni]])
+ AC_CACHE_CHECK([[whether GnuTLS require libgcrypt initialisaion]], [mhd_cv_gcrypt_required],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [
+#include <gnutls/gnutls.h>
+ ],
+ [
+#if !defined(GNUTLS_VERSION_NUMBER) || GNUTLS_VERSION_NUMBER+0 <= 0x020c14
+#error Old versions of GnuTLS require libgcript initialisaion
+choke me now
+#endif
+ ]
+ )
+ ],
+ [[mhd_cv_gcrypt_required='no']], [[mhd_cv_gcrypt_required='yes']]
+ )
+ ]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ CFLAGS="$SAVE_CFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+ LIBS="$SAVE_LIBS"
+ ],
+ [
+ AS_UNSET([GNUTLS_CPPFLAGS])
+ AS_UNSET([GNUTLS_LDFLAGS])
+ ]
+ )
-AC_SUBST([GNUTLS_CPPFLAGS])
-AC_SUBST([GNUTLS_CFLAGS])
-AC_SUBST([GNUTLS_LDFLAGS])
-AC_SUBST([GNUTLS_LIBS])
+ AS_IF([[test "x$mhd_cv_gcrypt_required" = "xyes" && test "x$have_gcrypt" = "xunknown"]],
+ [
+ AM_PATH_LIBGCRYPT([1.2.2], [have_gcrypt=yes], [have_gcrypt=no])
+ AS_IF([[test "x$have_gcrypt" = "xyes"]],
+ [
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
+ # LIBGCRYPT_CFLAGS can be actually a CPPFLAGS, so check them both
+ CPPFLAGS="$CPPFLAGS $LIBGCRYPT_CFLAGS"
+ AC_CHECK_HEADERS([gcrypt.h], [], [have_gcrypt=no], [AC_INCLUDES_DEFAULT])
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ CFLAGS="$SAVE_CFLAGS"
+ ]
+ )
+ ]
+ )
-#
-# End of large unindented block
-#
- AS_IF([test "x$have_gnutls" = "xyes" && test "x$have_gcrypt" = "xyes"], [
+ AS_UNSET([[crypt_missing]])
+ AS_IF([[test "x$have_gnutls" = "xyes"]],
+ [
+ AS_IF([[test "x$mhd_cv_gcrypt_required" = "xyes" && test "x$have_gcrypt" != "xyes"]],
+ [
+ crypt_missing="required libgcrypt"
+ AS_IF([[test "x$enable_https" = "xyes" ]], [AC_MSG_ERROR([[HTTPS support cannot be enabled without $crypt_missing.]])])
+ enable_https=no
+ MSG_HTTPS="no (lacking $crypt_missing)"
+ AS_UNSET([LIBGCRYPT_CFLAGS])
+ AS_UNSET([LIBGCRYPT_LIBS])
+ AS_UNSET([GNUTLS_CPPFLAGS])
+ AS_UNSET([GNUTLS_CFLAGS])
+ AS_UNSET([GNUTLS_LDFLAGS])
+ AS_UNSET([GNUTLS_LIBS])
+ ],
+ [
AC_DEFINE([[HTTPS_SUPPORT]],[[1]],[Define to 1 if libmicrohttpd is compiled with HTTPS support.])
enable_https=yes
- MSG_HTTPS="yes (using libgnutls and libgcrypt)"
- MHD_LIB_CPPFLAGS="$MHD_LIB_CPPFLAGS $LIBGCRYPT_CFLAGS $GNUTLS_CPPFLAGS"
- MHD_LIB_CFLAGS="$MHD_LIB_CFLAGS $LIBGCRYPT_CFLAGS $GNUTLS_CFLAGS"
- MHD_LIB_LDFLAGS="$MHD_LIB_LDFLAGS $GNUTLS_LDFLAGS"
- MHD_LIBDEPS="$GNUTLS_LIBS $LIBGCRYPT_LIBS $MHD_LIBDEPS"
+ AS_IF([[test "x$mhd_cv_gcrypt_required" = "xyes"]],
+ [
+ MSG_HTTPS="yes (using libgnutls and libgcrypt)"
+ MHD_TLS_LIB_CPPFLAGS="$LIBGCRYPT_CFLAGS $GNUTLS_CPPFLAGS"
+ MHD_TLS_LIB_CFLAGS="$LIBGCRYPT_CFLAGS $GNUTLS_CFLAGS"
+ MHD_TLS_LIB_LDFLAGS="$GNUTLS_LDFLAGS"
+ MHD_TLS_LIBDEPS="$GNUTLS_LIBS $LIBGCRYPT_LIBS"
+ AC_DEFINE([[MHD_HTTPS_REQUIRE_GCRYPT]], [[1]], [Define to `1' if HTTPS require initialisation of libgcrypt])
+ ],
+ [
+ MSG_HTTPS="yes (using libgnutls)"
+ AS_UNSET([LIBGCRYPT_CFLAGS])
+ AS_UNSET([LIBGCRYPT_LIBS])
+ MHD_TLS_LIB_CPPFLAGS="$GNUTLS_CPPFLAGS"
+ MHD_TLS_LIB_CFLAGS="$GNUTLS_CFLAGS"
+ MHD_TLS_LIB_LDFLAGS="$GNUTLS_LDFLAGS"
+ MHD_TLS_LIBDEPS="$GNUTLS_LIBS"
+ ]
+ )
AS_IF([[ test "x$have_gnutls_pkgcfg" = "xyes" ]],
[ # remove GnuTLS from private libs in .pc file as it defined in Requires.private
MHD_REQ_PRIVATE='gnutls'
- MHD_LIBDEPS_PKGCFG="$LIBGCRYPT_LIBS $MHD_LIBDEPS_PKGCFG"
+ AS_IF([[test "x$mhd_cv_gcrypt_required" = "xyes"]],
+ [[MHD_LIBDEPS_PKGCFG="$LIBGCRYPT_LIBS $MHD_LIBDEPS_PKGCFG"]]
+ )
],
[
MHD_REQ_PRIVATE=''
- MHD_LIBDEPS_PKGCFG="$GNUTLS_LIBS $LIBGCRYPT_LIBS $MHD_LIBDEPS_PKGCFG"
+ AS_IF([[test "x$mhd_cv_gcrypt_required" = "xyes"]],
+ [[MHD_LIBDEPS_PKGCFG="$LIBGCRYPT_LIBS $MHD_LIBDEPS_PKGCFG"]]
+ )
+ MHD_LIBDEPS_PKGCFG="$GNUTLS_LIBS $MHD_LIBDEPS_PKGCFG"
])
- ], [
- AS_IF([test "x$have_gnutls" = "xyes"], [crypt_missing="libgcrypt"],
- [test "x$have_gcrypt" = "xyes"], [crypt_missing="libgnutls"],
- [crypt_missing="libgcrypt and libgnutls"])
- AS_IF([[test "x$enable_https" = "xyes" ]], [AC_MSG_ERROR([[HTTPS support cannot be enabled without $crypt_missing.]])])
- enable_https=no
- MSG_HTTPS="no (lacking $crypt_missing)"
- ])
-else
+ ]
+ )
+ ],
+ [
+ crypt_missing="libgnutls"
+ AS_IF([[test "x$enable_https" = "xyes" ]], [AC_MSG_ERROR([[HTTPS support cannot be enabled without $crypt_missing.]])])
+ enable_https=no
+ MSG_HTTPS="no (lacking $crypt_missing)"
+ AS_UNSET([LIBGCRYPT_CFLAGS])
+ AS_UNSET([LIBGCRYPT_LIBS])
+ AS_UNSET([GNUTLS_CPPFLAGS])
+ AS_UNSET([GNUTLS_CFLAGS])
+ AS_UNSET([GNUTLS_LDFLAGS])
+ AS_UNSET([GNUTLS_LIBS])
+ ]
+ )
+],[
MSG_HTTPS="no (disabled)"
-fi
+])
+
+#
+# End of large unindented block
+#
+
+
AC_MSG_CHECKING(whether to support HTTPS)
AC_MSG_RESULT([$MSG_HTTPS])
AM_CONDITIONAL([HAVE_GNUTLS], [[test "x$have_gnutls" = "xyes"]])
AM_CONDITIONAL([HAVE_GNUTLS_SNI], [[test "x$have_gnutls_sni" = "xyes"]])
AM_CONDITIONAL([ENABLE_HTTPS], [test "x$enable_https" = "xyes"])
+AM_CONDITIONAL([HTTPS_REQUIRE_GCRYPT], [[test "x$enable_https" = "xyes" && test "x$mhd_cv_gcrypt_required" = "xyes"]])
+AC_SUBST([GNUTLS_CPPFLAGS])
+AC_SUBST([GNUTLS_CFLAGS])
+AC_SUBST([GNUTLS_LDFLAGS])
+AC_SUBST([GNUTLS_LIBS])
# optional: HTTP Basic Auth support. Enabled by default
AC_MSG_CHECKING([[whether to support HTTP basic authentication]])
@@ -1370,6 +2172,99 @@
AS_VAR_IF([[mhd_cv_have_func_calloc]], [["yes"]],
[AC_DEFINE([[HAVE_CALLOC]], [[1]], [Define to 1 if you have the usable `calloc' function.])])
+# Some systems have IPv6 disabled in kernel at run-time
+AS_IF([[test "x${have_inet6}" = "xyes" && test "x${cross_compiling}" = "xno"]],
+ [
+ AC_CACHE_CHECK([whether IPv6 could be used for testing],[mhd_cv_ipv6_for_testing],
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_SOURCE([[
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+static void zr_mem(void *ptr, socklen_t size)
+{ char *mem = ptr; while(size--) {mem[0] = 0; mem++;} }
+
+int main(void)
+{
+ int ret = 30;
+ struct sockaddr_in6 sa;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ int sckt;
+ const int invld_sckt = -1;
+#else
+ SOCKET sckt;
+ const SOCKET invld_sckt = INVALID_SOCKET;
+ WSADATA wsa_data;
+
+ WSAStartup(MAKEWORD(2, 2), &wsa_data);
+#endif
+ zr_mem(&sa, sizeof(sa));
+ sa.sin6_family = AF_INET6;
+ sa.sin6_port = 0;
+ sa.sin6_addr = in6addr_loopback;
+#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
+ sa.sin6_len = sizeof(sa);
+#endif
+ sckt = socket (PF_INET6, SOCK_STREAM, 0);
+ if (invld_sckt != sckt)
+ {
+ if (0 == bind (sckt, (struct sockaddr *)&sa, sizeof(sa)))
+ {
+ if (0 == listen (sckt, 1))
+ ret = 0;
+ else
+ ret = 1; /* listen() failed */
+ } else ret = 2; /* bind() failed */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ close (sckt);
+#else
+ closesocket (sckt);
+#endif
+ } else ret = 3; /* socket() failed */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ WSACleanup();
+#endif
+ return ret;
+}
+ ]])
+ ], [[mhd_cv_ipv6_for_testing="yes"]], [[mhd_cv_ipv6_for_testing="no"]], [[mhd_cv_ipv6_for_testing="no"]]
+ )
+ ]
+ )
+ ]
+)
+AS_VAR_IF([mhd_cv_ipv6_for_testing],["yes"],
+ [AC_DEFINE([[USE_IPV6_TESTING]], [[1]], [Define to 1 if your kernel supports IPv6 and IPv6 is enabled and useful for testing.])]
+)
+
+
# Check for fork() and waitpid(). They are used for tests.
AC_MSG_CHECKING([[for fork()]])
mhd_have_fork_waitpid='no'
@@ -1417,8 +2312,6 @@
AM_CONDITIONAL([HAVE_FORK_WAITPID], [test "x$mhd_have_fork_waitpid" = "xyes"])
-MHD_LIB_LDFLAGS="$MHD_LIB_LDFLAGS -export-dynamic -no-undefined"
-
# gcov compilation
AC_MSG_CHECKING(whether to compile with support for code coverage analysis)
AC_ARG_ENABLE([coverage],
@@ -1430,12 +2323,53 @@
AM_CONDITIONAL([USE_COVERAGE], [test "x$use_gcov" = "xyes"])
AX_COUNT_CPUS
+AS_IF([[test "$CPU_COUNT" -gt "32"]], [[CPU_COUNT="32"]])dnl Limit resource usage
AC_SUBST([CPU_COUNT])
+AC_MSG_CHECKING([[whether to enable debug asserts]])
+AC_ARG_ENABLE([[asserts]],
+ AS_HELP_STRING([[--enable-asserts]],
+ [enable test build with debug asserts]),
+ [], [[enable_asserts='no']])
+AS_CASE([[$enable_asserts]], [[yes]], [[:]], [[no]], [[:]], [[enable_asserts='no']])
+AC_MSG_RESULT([[$enable_asserts]])
+
+AS_VAR_IF([[enable_asserts]], [["yes"]],
+ [
+ AC_DEFINE([[_DEBUG]], [[1]], [Define to use debug asserts.])
+ [mhd_assert_test_prg="#include <assert.h>
+ int pos_val(void) {return 5;}
+ int neg_val(void) {return -5;}
+ int main(void)
+ { int pos_var = pos_val(), neg_var = neg_val();
+ assert(neg_var > pos_var); /* Must trigger assert. */
+ (void)pos_var; (void)neg_var;
+ return 0; }
+ "]
+ AC_CACHE_CHECK([[whether system assert() is available]], [mhd_cv_sys_assert_avail],
+ [
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[$mhd_assert_test_prg]])],
+ [[mhd_cv_sys_assert_avail='yes']],
+ [[mhd_cv_sys_assert_avail='no']])
+ ]
+ )
+ AS_VAR_IF([[mhd_cv_sys_assert_avail]], [["no"]], [],
+ [AC_DEFINE([[HAVE_ASSERT]], [[1]], [Define if you have usable assert() and assert.h])])
+ AS_UNSET([mhd_assert_test_prg])
+ ],
+ [AC_DEFINE([[NDEBUG]], [[1]], [Define to disable usage of debug asserts.])]
+)
+
+MHD_LIB_LDFLAGS="$MHD_LIB_LDFLAGS -export-dynamic -no-undefined"
+
AC_SUBST(MHD_LIB_CPPFLAGS)
AC_SUBST(MHD_LIB_CFLAGS)
AC_SUBST(MHD_LIB_LDFLAGS)
AC_SUBST(MHD_LIBDEPS)
+AC_SUBST(MHD_TLS_LIB_CPPFLAGS)
+AC_SUBST(MHD_TLS_LIB_CFLAGS)
+AC_SUBST(MHD_TLS_LIB_LDFLAGS)
+AC_SUBST(MHD_TLS_LIBDEPS)
# for pkg-config
AC_SUBST([MHD_REQ_PRIVATE])
@@ -1449,18 +2383,35 @@
AC_SUBST([ac_configure_args])
AC_SUBST([EMPTY_VAR], [[]])
-AC_CONFIG_FILES([
-libmicrohttpd.pc
+# We define the paths here, because MinGW/GCC expands paths
+# passed through the command line ("-DDIR=..."). This would
+# lead to hard-coded paths ("C:\mingw\mingw\bin...") that do
+# not contain the actual installation.
+AC_DEFINE_DIR([MHD_PLUGIN_INSTALL_PREFIX], [libdir/libmicrohttpd], [tls plugins])
+
+
+# should experimental code be compiled (code that may not yet compile)?
+AC_MSG_CHECKING(whether to compile experimental code)
+AC_ARG_ENABLE([experimental],
+ [AS_HELP_STRING([--enable-experimental], [enable compiling experimental code])],
+ [enable_experimental=${enableval}],
+ [enable_experimental=no])
+AC_MSG_RESULT($enable_experimental)
+AM_CONDITIONAL([HAVE_EXPERIMENTAL], [test "x$enable_experimental" = "xyes"])
+
+
+AC_CONFIG_FILES([libmicrohttpd.pc
w32/common/microhttpd_dll_res_vc.rc
-po/configure.acT:po/configure.ac.in
Makefile
contrib/Makefile
doc/Makefile
+doc/doxygen/libmicrohttpd.doxy
doc/doxygen/Makefile
doc/examples/Makefile
m4/Makefile
src/Makefile
src/include/Makefile
+src/lib/Makefile
src/microhttpd/Makefile
src/examples/Makefile
src/testcurl/Makefile
@@ -1469,49 +2420,49 @@
AC_OUTPUT
# Finally: summary
-if test "x$enable_curl" != "xyes"; then
- MSG_CURL="no, many unit tests will not run"
-else
- MSG_CURL="yes"
-fi
+AS_IF([test "x$enable_curl" != "xyes"],
+ [MSG_CURL="no, many unit tests will not run"],
+ [MSG_CURL="yes"])
+
+AS_VAR_IF([os_is_windows], ["yes"],
+ [os_ver_msg="
+ Target W32 ver: ${mhd_w32_ver_msg}"], [AS_UNSET([[os_ver_msg]])])
+
-AC_MSG_NOTICE([libmicrohttpd ${PACKAGE_VERSION} Configuration Summary:
+AC_MSG_NOTICE([GNU libmicrohttpd ${PACKAGE_VERSION} Configuration Summary:
+ Target directory: ${prefix}
Cross-compiling: ${cross_compiling}
- Operating System: ${host_os}
+ Operating System: ${host_os}${os_ver_msg}
+ Shutdown of listening socket triggers select: ${mhd_cv_host_shtdwn_trgr_select}
+ Inter-thread comm: ${use_itc}
+ poll support: ${enable_poll=no}
+ epoll support: ${enable_epoll=no}
+ sendfile used: ${found_sendfile}
+ HTTPS support: ${MSG_HTTPS}
Threading lib: ${USE_THREADS}
Use thread names: ${enable_thread_names}
- Inter-thread comm: ${use_itc}
- libcurl (testing): ${MSG_CURL}
- Target directory: ${prefix}
- Shutdown of listening socket
- trigger select: ${mhd_cv_host_shtdwn_trgr_select}
+ Use debug asserts: ${enable_asserts}
Messages: ${enable_messages}
+ Gettext: ${have_po}
Basic auth.: ${enable_bauth}
Digest auth.: ${enable_dauth}
HTTP "Upgrade": ${enable_httpupgrade}
Postproc: ${enable_postprocessor}
- HTTPS support: ${MSG_HTTPS}
- poll support: ${enable_poll=no}
- epoll support: ${enable_epoll=no}
- build docs: ${enable_doc}
- build examples: ${enable_examples}
+ Build docs: ${enable_doc}
+ Build examples: ${enable_examples}
+ Test with libcurl: ${MSG_CURL}
])
-if test "x$enable_https" = "xyes"
-then
- AC_MSG_NOTICE([HTTPS subsystem configuration:
- License : LGPL only
- ])
-else
- AC_MSG_NOTICE([
- License : LGPL or eCos
-])
-fi
+AS_IF([test "x$enable_https" = "xyes"],
+ [AC_MSG_NOTICE([HTTPS subsystem configuration:
+ License : LGPLv2.1+ only
+ ])],
+ [AC_MSG_NOTICE([
+ License : LGPLv2.1+ or eCos
+ ])])
-if test "x$enable_bauth" != "xyes" || \
+AS_IF([test "x$enable_bauth" != "xyes" || \
test "x$enable_dauth" != "xyes" || \
test "x$enable_httpupgrade" != "xyes" || \
- test "x$enable_postprocessor" != "xyes"
-then
- AC_MSG_NOTICE([WARNING: This will be a custom build with missing symbols. Do NOT use this build in a distribution. Building with these kinds of configure options is only for custom builds for embedded systems.])
-fi
+ test "x$enable_postprocessor" != "xyes"],
+ [AC_MSG_NOTICE([WARNING: This will be a custom build with missing symbols. Do NOT use this build in a distribution. Building with these kinds of configure options is only for custom builds for embedded systems.])])
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common
^
|
+(directory)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/.gitignore
^
|
@@ -0,0 +1,2 @@
+config.mk
+__pycache__
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/.style.yapf
^
|
+(symlink to conf/.style.yapf)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/LICENSE
^
|
@@ -0,0 +1,13 @@
+Copyright (C) 2019 by GNUnet eV
+
+Permission to use, copy, modify, and/or distribute this software for
+any purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/README
^
|
@@ -0,0 +1,31 @@
+Shared build-system files for (some) parts of Taler.
+
+A repository using these build-system files should be structured as follows:
+
+<my-repository.git>
+- bootstrap (copied/adjusted from bootstrap.template)
+- build-system (directory containing build system "stuff")
+--| configure.py (copied/adjusted from bootstrap.template)
+--| taler-build-scripts (git submodule of taler-build-scripts)
+--| Makefile
+
+Makefile and configure.py can also be placed directly into the root of the
+repository. However, this might lead to errors when "make" can be invoked
+before bootstrap and configure has been done.
+
+
+directory structure:
+--------------------
+
+conf:
+- contains mixed configuration data, mostly for linters and editors
+
+sh:
+- contains shell script code in reusable, importable pieces,
+ usually one function per file and files named after their
+ function.
+ the sh/lib.sh folder contains library code.
+ the sh/bin.sh folder contains executable scripts which can be
+ used for various functions.
+ Current caveat: the files all have to be included. shell independent
+ detection of real pathnames is tricky.
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/bootstrap.template
^
|
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Bootstrap the repository. Used when the repository is checked out from git.
+# When using the source tarball, running this script is not necessary.
+
+set -eu
+
+if ! git --version >/dev/null; then
+ echo "git not installed"
+ exit 1
+fi
+
+git submodule update --init
+ln -sf build-system/taler-build-scripts/configure ./configure
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.dir-locals.el
^
|
@@ -0,0 +1,16 @@
+;; Per-directory local variables for GNU Emacs 23 and later.
+
+((nil
+ . ((fill-column . 78)
+ (tab-width . 4)
+ (indent-tabs-mode . nil)
+ (show-trailing-whitespace . t)
+ (c-basic-offset . 2)
+ (ispell-check-comments . exclusive)
+ (ispell-local-dictionary . "american")
+ (safe-local-variable-values
+ '((c-default-style . "gnu")
+ (sentence-end-double-space . f)
+ (eval add-hook 'prog-mode-hook #'flyspell-prog-mode)
+ (flyspell-issue-message-flag . f) ; avoid messages for every word
+ )))))
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.prettierrc
^
|
@@ -0,0 +1,6 @@
+{
+ "trailingComma": "all",
+ "tabWidth": 2,
+ "semi": true,
+ "singleQuote": false
+}
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.style.yapf
^
|
@@ -0,0 +1,5 @@
+[style]
+based_on_style = pep8
+coalesce_brackets=True
+column_limit=80
+dedent_closing_brackets=True
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.vscode/settings.json
^
|
@@ -0,0 +1,40 @@
+// Place your settings in this file to overwrite default and user settings.
+{
+ // Use latest language servicesu
+ "typescript.tsdk": "./node_modules/typescript/lib",
+ // Defines space handling after a comma delimiter
+ "typescript.format.insertSpaceAfterCommaDelimiter": true,
+ // Defines space handling after a semicolon in a for statement
+ "typescript.format.insertSpaceAfterSemicolonInForStatements": true,
+ // Defines space handling after a binary operator
+ "typescript.format.insertSpaceBeforeAndAfterBinaryOperators": true,
+ // Defines space handling after keywords in control flow statement
+ "typescript.format.insertSpaceAfterKeywordsInControlFlowStatements": true,
+ // Defines space handling after function keyword for anonymous functions
+ "typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": true,
+ // Defines space handling after opening and before closing non empty parenthesis
+ "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
+ // Defines space handling after opening and before closing non empty brackets
+ "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
+ // Defines whether an open brace is put onto a new line for functions or not
+ "typescript.format.placeOpenBraceOnNewLineForFunctions": false,
+ // Defines whether an open brace is put onto a new line for control blocks or not
+ "typescript.format.placeOpenBraceOnNewLineForControlBlocks": false,
+ // Files hidden in the explorer
+ "files.exclude": {
+ // include the defaults from VS Code
+ "**/.git": true,
+ "**/.DS_Store": true,
+ // exclude .js and .js.map files, when in a TypeScript project
+ "**/*.js": {
+ "when": "$(basename).ts"
+ },
+ "**/*?.js": {
+ "when": "$(basename).tsx"
+ },
+ "**/*.js.map": true
+ },
+ "tslint.enable": true,
+ "editor.wrappingIndent": "same",
+ "editor.tabSize": 2
+}
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.vscode/tasks.json
^
|
@@ -0,0 +1,44 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "typescript",
+ "tsconfig": "tsconfig.json",
+ "option": "watch",
+ "problemMatcher": [
+ "$tsc-watch"
+ ],
+ "group": "build",
+ "isBackground": true,
+ "promptOnClose": false
+ },
+ {
+ "type": "typescript",
+ "tsconfig": "tsconfig.json",
+ "problemMatcher": [
+ "$tsc"
+ ],
+ "group": "build"
+ },
+ {
+ "label": "tslint",
+ "type": "shell",
+ "command": "make lint",
+ "problemMatcher": {
+ "owner": "tslint",
+ "applyTo": "allDocuments",
+ "fileLocation": "absolute",
+ "severity": "warning",
+ "pattern": "$tslint5"
+ },
+ "group": "build"
+ },
+ {
+ "label": "My Task",
+ "type": "shell",
+ "command": "echo Hello"
+ }
+ ]
+}
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/.yarnrc
^
|
@@ -0,0 +1,2 @@
+yarn-offline-mirror "./npm-packages-offline-cache"
+yarn-offline-mirror-pruning true
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/uncrustify-mode.el
^
|
@@ -0,0 +1,161 @@
+;;; uncrustify-mode.el --- Minor mode to automatically uncrustify.
+
+;; Copyright (C) 2012 tabi
+;; Author: Tabito Ohtani <koko1000ban@gmail.com>
+;; Version: 0.01
+;; Keywords: uncrustify
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Installation:
+
+;; drop requirements and this file into a directory in your `load-path',
+;; and put these lines into your .emacs file.
+
+;; (require 'uncrusfify-mode)
+;; (add-hook 'c-mode-common-hook
+;; '(lambda ()
+;; (uncrustify-mode 1)))
+
+;;; ChangeLog:
+;; * 0.0.1:
+;; Initial version.
+
+
+;; case
+(eval-when-compile
+ (require 'cl))
+
+;;; Variables:
+
+(defcustom uncrustify-config-path
+ "~/.uncrustify.cfg"
+ "uncrustify config file path"
+ :group 'uncrustify
+ :type 'file)
+(make-variable-buffer-local 'uncrustify-config-path)
+
+(defcustom uncrustify-bin
+ "uncrustify -q"
+ "The command to run uncrustify."
+ :group 'uncrustify)
+
+;;; Functions:
+
+(defun uncrustify-get-lang-from-mode (&optional mode)
+ "uncrustify lang option"
+ (let ((m (or mode major-mode)))
+ (case m
+ ('c-mode "C")
+ ('c++-mode "CPP")
+ ('d-mode "D")
+ ('java-mode "JAVA")
+ ('objc-mode "OC")
+ (t
+ nil))))
+
+(defun uncrustify-point->line (point)
+ "Get the line number that POINT is on."
+ ;; I'm not bothering to use save-excursion because I think I'm
+ ;; calling this function from inside other things that are likely to
+ ;; use that and all I really need to do is restore my current
+ ;; point. So that's what I'm doing manually.
+ (let ((line 1)
+ (original-point (point)))
+ (goto-char (point-min))
+ (while (< (point) point)
+ (incf line)
+ (forward-line))
+ (goto-char original-point)
+ line))
+
+(defun uncrustify-invoke-command (lang start-in end-in)
+ "Run uncrustify on the current region or buffer."
+ (if lang
+ (let ((start (or start-in (point-min)))
+ (end (or end-in (point-max)))
+ (original-line (uncrustify-point->line (point)))
+ (cmd (concat uncrustify-bin " -c " uncrustify-config-path " -l " lang))
+ (out-buf (get-buffer-create "*uncrustify-out*"))
+ (error-buf (get-buffer-create "*uncrustify-errors*")))
+
+ (with-current-buffer error-buf (erase-buffer))
+ (with-current-buffer out-buf (erase-buffer))
+
+ ;; Inexplicably, save-excursion doesn't work to restore the
+ ;; point. I'm using it to restore the mark and point and manually
+ ;; navigating to the proper new-line.
+ (let ((result
+ (save-excursion
+ (let ((ret (shell-command-on-region start end cmd t t error-buf nil)))
+ (if (and
+ (numberp ret)
+ (zerop ret))
+ ;; Success! Clean up.
+ (progn
+ (message "Success! uncrustify modify buffer.")
+ (kill-buffer error-buf)
+ t)
+ ;; Oops! Show our error and give back the text that
+ ;; shell-command-on-region stole.
+ (progn (undo)
+ (with-current-buffer error-buf
+ (message "uncrustify error: <%s> <%s>" ret (buffer-string)))
+ nil))))))
+
+ ;; This goto-line is outside the save-excursion becuase it'd get
+ ;; removed otherwise. I hate this bug. It makes things so ugly.
+ (goto-line original-line)
+ (not result)))
+ (message "uncrustify not support this mode : %s" major-mode)))
+
+(defun uncrustify ()
+ (interactive)
+ (save-restriction
+ (widen)
+ (uncrustify-invoke-command (uncrustify-get-lang-from-mode) (region-beginning) (region-end))))
+
+(defun uncrustify-buffer ()
+ (interactive)
+ (save-restriction
+ (widen)
+ (uncrustify-invoke-command (uncrustify-get-lang-from-mode) (point-min) (point-max))))
+
+;;; mode
+
+(defun uncrustify-write-hook ()
+ "Uncrustifys a buffer during `write-file-hooks' for `uncrustify-mode'.
+ if uncrustify returns not nil then the buffer isn't saved."
+ (if uncrustify-mode
+ (save-restriction
+ (widen)
+ (uncrustify-invoke-command (uncrustify-get-lang-from-mode) (point-min) (point-max)))))
+
+;;;###autoload
+(define-minor-mode uncrustify-mode
+ "Automatically `uncrustify' when saving."
+ :lighter " Uncrustify"
+ (if (not (uncrustify-get-lang-from-mode))
+ (message "uncrustify not support this mode : %s" major-mode)
+ (if (version<= "24" emacs-version)
+ (if uncrustify-mode
+ (add-hook 'write-file-hooks 'uncrustify-write-hook nil t)
+ (remove-hook 'uncrustify-write-hook t))
+ (make-local-hook 'write-file-hooks)
+ (funcall (if uncrustify-mode #'add-hook #'remove-hook)
+ 'write-file-hooks 'uncrustify-write-hook))))
+
+(provide 'uncrustify-mode)
+
+;;; uncrustify-mode.el ends here
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/uncrustify.cfg
^
|
@@ -0,0 +1,78 @@
+input_tab_size = 2
+output_tab_size = 2
+
+indent_columns = 2
+indent_with_tabs = 0
+indent_case_brace = 2
+indent_label=0
+
+code_width=80
+#cmd_width=80
+
+# Leave most comments alone for now
+cmt_indent_multi=false
+sp_cmt_cpp_start=add
+
+sp_not=add
+
+sp_func_call_user_paren_paren=remove
+sp_inside_fparen=remove
+sp_after_cast=add
+
+ls_for_split_full=true
+ls_func_split_full=true
+ls_code_width=true
+
+# Arithmetic operations in wrapped expressions should be at the start
+# of the line.
+pos_arith=lead
+
+# Fully parenthesize boolean exprs
+mod_full_paren_if_bool=true
+
+# Braces should be on their own line
+nl_fdef_brace=add
+nl_enum_brace=add
+nl_struct_brace=add
+nl_union_brace=add
+nl_if_brace=add
+nl_brace_else=add
+nl_elseif_brace=add
+nl_while_brace=add
+nl_switch_brace=add
+
+# no newline between "else" and "if"
+nl_else_if=remove
+
+nl_func_paren=remove
+nl_assign_brace=remove
+
+# No extra newlines that cause noisy diffs
+nl_start_of_file=remove
+# If there's no new line, it's not a text file!
+nl_end_of_file=add
+
+sp_inside_paren = remove
+
+sp_arith = add
+sp_arith_additive = add
+
+# We want spaces before and after "="
+sp_before_assign = add
+sp_after_assign = add
+
+# we want "char *foo;"
+sp_after_ptr_star = remove
+sp_between_ptr_star = remove
+
+# we want "if (foo) { ... }"
+sp_before_sparen = add
+
+sp_inside_fparen = remove
+
+# add space before function call and decl: "foo (x)"
+sp_func_call_paren = add
+sp_func_proto_paren = add
+sp_func_proto_paren_empty = add
+sp_func_def_paren = add
+sp_func_def_paren_empty = add
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/uncrustify.el
^
|
@@ -0,0 +1,13 @@
+;; suggested integration of uncrustify for Emacs
+;; This assumes that the 'uncrustify-mode.el' is
+;; installed to '~/.emacs.d/load-path/'. Feel free
+;; to put it elsewhere and adjust the load path below!
+
+;; adding the following to ~/.emacs will then run
+;; uncrustify whenever saving a C buffer.
+
+(add-to-list 'load-path "~/.emacs.d/load-path/")
+(require 'uncrustify-mode)
+(add-hook 'c-mode-common-hook
+ '(lambda ()
+ (uncrustify-mode 1)))
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/conf/uncrustify.sh
^
|
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -eu
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+if ! uncrustify --version >/dev/null; then
+ echo "you need to install uncrustify for indentation"
+ exit 1
+fi
+
+find "$DIR/../src" \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) \
+ -exec uncrustify -c "$DIR/uncrustify.cfg" --replace --no-backup {} + \
+ || true
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/configure
^
|
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# This file is part of TALER
+# (C) 2019 GNUnet e.V.
+#
+# This is very simple POSIX sh script which
+# identifies the first matching
+# python3 identifier in $PATH and produces
+# configure.py from configure.py.in, and then
+# calls the new executable configure.py.
+#
+# It should be portable on Unices. Report bugs on
+# the bugtracker if you discover that it isn't
+# working as intended.
+#
+# Authors:
+# Author: ng0 <ng0@taler.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+#
+# SPDX-License-Identifier: 0BSD
+
+# we invoke configure not as a symlink but as a copy,
+# so we have to use a fixed location for the repository!
+dir=$(dirname "$(readlink -f -- "$0")")/build-system/taler-build-scripts
+. $dir/sh/lib.sh/existence.sh
+. $dir/sh/lib.sh/existence_python.sh
+
+scriptpath=build-system/taler-build-scripts
+
+if ! test -d "$scriptpath"; then
+ echo "fatal error: taler-build-scripts not found at $scriptpath" >&2
+ exit 1
+fi
+
+export PYTHONPATH="$scriptpath:${PYTHONPATH:-}"
+
+# Call configure.py, assuming all went well.
+# $1 is read by configure.py as the prefix.
+# If $1 is empty, the python script checks the
+# environment for PREFIX. We might need more
+# variables and switches, such as DESTDIR.
+exec "$PYTHON" ./configure.py $@
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/configure.py.template
^
|
@@ -0,0 +1,9 @@
+# This configure.py.template file is in the public domain.
+
+from talerbuildconfig import *
+
+b = BuildConfig()
+b.enable_prefix()
+b.enable_configmk()
+b.add_tool(PosixTool("find"))
+b.run()
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/coverage.sh
^
|
@@ -0,0 +1,10 @@
+#!/bin/sh
+# Run from 'taler-exchange/' top-level directory to generate
+# code coverage data.
+TOP=`pwd`
+mkdir -p doc/coverage/
+lcov -d $TOP -z
+make check
+lcov -d $TOP -c --no-external -o doc/coverage/coverage.info
+lcov -r doc/coverage/coverage.info **/test_* **/perf_* -o doc/coverage/rcoverage.info
+genhtml -o doc/coverage doc/coverage/rcoverage.info
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/sh/bin.sh/python.sh
^
|
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# This file is part of TALER
+# (C) 2019 GNUnet e.V.
+#
+# This is very simple POSIX sh script which
+# identifies the first matching
+# python3 identifier in $PATH and produces
+# configure.py from configure.py.in, and then
+# calls the new executable configure.py.
+#
+# It should be portable on Unices. Report bugs on
+# the bugtracker if you discover that it isn't
+# working as intended.
+#
+# Authors:
+# Author: ng0 <ng0@taler.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+#
+# SPDX-License-Identifier: 0BSD
+
+dir=$(dirname "$(readlink -f -- "$0")")
+. $dir/../lib.sh/existence.sh
+. $dir/../lib.sh/existence_python.sh
+
+exec "$PYTHON" $@
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/sh/lib.sh/existence.sh
^
|
@@ -0,0 +1,27 @@
+# This file is part of TALER
+# (C) 2019 GNUnet e.V.
+#
+# Authors:
+# Author: ng0 <ng0@taler.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+#
+# SPDX-License-Identifier: 0BSD
+
+# there is a function used in curl to replicate which(1), but
+# it uses too many other tools. this one uses command and in
+# gnunet so far has no reports about failures.
+existence()
+{
+ command -v "$1" >/dev/null 2>&1
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/sh/lib.sh/existence_python.sh
^
|
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+# This file is part of TALER
+# (C) 2019 GNUnet e.V.
+#
+# This is very simple POSIX sh script which
+# identifies the first matching
+# python3 identifier in $PATH and produces
+# configure.py from configure.py.in, and then
+# calls the new executable configure.py.
+#
+# It should be portable on Unices. Report bugs on
+# the bugtracker if you discover that it isn't
+# working as intended.
+#
+# Authors:
+# Author: ng0 <ng0@taler.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+#
+# SPDX-License-Identifier: 0BSD
+
+existence_python()
+{
+ # We have to check every possible variant of the
+ # executable name because there is a PEP which
+ # defines the executable to be like this.
+ if existence python3; then
+ if test ! -z "`python3 --version | awk '$2 ~ /3.7/ { print }'`"; then
+ python="python3"
+ else
+ echo "*** At least python 3.7 is required for the buildsystem"
+ exit 1
+ fi
+ # elif existence python3.1; then
+ # python="python3.1"
+ # elif existence python3.2; then
+ # python="python3.2"
+ # elif existence python3.3; then
+ # python="python3.3"
+ # elif existence python3.4; then
+ # python="python3.4"
+ # elif existence python3.5; then
+ # python="python3.5"
+ # elif existence python3.6; then
+ # python="python3.6"
+ elif existence python3.7; then
+ python="python3.7"
+ elif existence python3.8; then
+ python="python3.8"
+ else
+ echo "*** No known python3 executable found in path ***"
+ echo "*** falling back to env(1) python ***"
+ # Unreliable, but if env finds no python, we still can
+ # not assume python in a fixed location.
+ # TODO: Check this in a clean chroot!
+ python="env python"
+ fi
+
+ # we could check the return value here via || echo "blafoo"
+ # or fail anyway once configure.py is invoked because we
+ # don't have python if we reach the point to fail.
+ PYTHON=$($python -c 'import sys; print(sys.executable)')
+}
+
+existence_python
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/talerbuildconfig.py
^
|
@@ -0,0 +1,328 @@
+# This file is part of TALER
+# (C) 2019 GNUnet e.V.
+#
+# Authors:
+# Author: ng0 <ng0@taler.net>
+# Author: Florian Dold <dold@taler.net>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+#
+# SPDX-License-Identifier: 0BSD
+
+from abc import ABC
+import argparse
+import os
+import sys
+import shlex
+import logging
+from distutils.spawn import find_executable
+import subprocess
+from dataclasses import dataclass
+
+"""
+This module aims to replicate a small GNU Coding Standards
+configure script, taylored at projects in GNU Taler. We hope it
+can be of use outside of GNU Taler, hence it is dedicated to the
+public domain ('0BSD').
+It takes a couple of arguments on the commandline equivalent to
+configure by autotools, in addition some environment variables
+xan take precedence over the switches. In the absence of switches,
+/usr/local is assumed as the PREFIX.
+When all data from tests are gathered, it generates a config.mk
+Makefile fragement, which is the processed by a Makefile (usually) in
+GNU Make format.
+"""
+
+
+# TODO: We need a smallest version argument.
+
+class Tool(ABC):
+ def args(self):
+ ...
+
+ def check(self, buildconfig):
+ ...
+
+
+class BuildConfig:
+ def __init__(self):
+ # Pairs of (key, value) for config.mk variables
+ self.make_variables = []
+ self.tools = []
+ self.tool_results = {}
+ self.args = None
+ self.prefix_enabled = False
+ self.configmk_enabled = False
+
+ def add_tool(self, tool):
+ if isinstance(tool, Tool):
+ self.tools.append(tool)
+ else:
+ raise Exception("Not a tool instance: " + repr(tool))
+
+ def _set_tool(self, name, value, version=None):
+ self.tool_results[name] = (value, version)
+
+ def enable_prefix(self):
+ """If enabled, process the --prefix argument."""
+ self.prefix_enabled = True
+
+ def enable_configmk(self):
+ """If enabled, output the config.mk makefile fragment."""
+ self.configmk_enabled = True
+
+ def run(self):
+ parser = argparse.ArgumentParser()
+ if self.prefix_enabled:
+ parser.add_argument(
+ "--prefix",
+ type=str,
+ default="/usr/local",
+ help="Directory prefix for installation",
+ )
+ for tool in self.tools:
+ tool.args(parser)
+ args = self.args = parser.parse_args()
+
+ for tool in self.tools:
+ res = tool.check(self)
+ if not res:
+ print(f"Error: tool {tool.name} not available")
+ if hasattr(tool, "hint"):
+ print(f"Hint: {tool.hint}")
+
+ for tool in self.tools:
+ path, version = self.tool_results[tool.name]
+ if version is None:
+ print(f"found {tool.name} as {path}")
+ else:
+ print(f"found {tool.name} as {path} (version {version})")
+
+ if self.configmk_enabled:
+ with open("config.mk", "w") as f:
+ print("writing config.mk")
+ f.write("# this makefile fragment is autogenerated by configure.py\n")
+ if self.prefix_enabled:
+ f.write(f"prefix = {args.prefix}\n")
+ for tool in self.tools:
+ path, version = self.tool_results[tool.name]
+ f.write(f"{tool.name} = {path}\n")
+
+
+def existence(name):
+ return find_executable(name) is not None
+
+
+class YarnTool(Tool):
+ name = "yarn"
+ description = "The yarn package manager for node"
+
+ def args(self, parser):
+ parser.add_argument("--with-yarn", action="store")
+
+ def check(self, buildconfig):
+ yarn_arg = buildconfig.args.with_yarn
+ if yarn_arg is not None:
+ buildconfig._set_tool("yarn", yarn_arg)
+ return True
+ if existence("yarn"):
+ p1 = subprocess.run(
+ ["yarn", "help"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE
+ )
+ if "No such file or directory" in p1.stdout.decode("utf-8"):
+ if existence("cmdtest"):
+ buildconfig._warn(
+ "cmdtest is installed, this can lead to known issues with yarn."
+ )
+ buildconfig._error(
+ "You seem to have the wrong kind of 'yarn' installed.\n"
+ "Please remove the conflicting binary before proceeding"
+ )
+ return False
+ yarn_version = tool_version("yarn --version")
+ buildconfig._set_tool("yarn", "yarn", yarn_version)
+ return True
+ elif existence("yarnpkg"):
+ yarn_version = tool_version("yarnpkg --version")
+ buildconfig._set_tool("yarn", "yarnpkg", yarn_version)
+ return True
+ return False
+
+
+def tool_version(name):
+ return subprocess.getstatusoutput(name)[1]
+
+
+class EmscriptenTool:
+ def args(self, parser):
+ pass
+
+ def check(self, buildconfig):
+ if existence("emcc"):
+ emscripten_version = tool_version("emcc --version")
+ buildconfig._set_tool("emcc", "emcc", emscripten_version)
+ return True
+ return False
+
+
+class PyBabelTool(Tool):
+ name = "pybabel"
+
+ def args(self, parser):
+ parser.add_argument(
+ "--with-pybabel", type=str, help="name of the pybabel executable"
+ )
+
+ def check(self, buildconfig):
+ # No suffix. Would probably be cheaper to do this in
+ # the dict as well. We also need to check the python
+ # version it was build against (TODO).
+ if existence("pybabel"):
+ import babel
+ pybabel_version = babel.__version__
+ buildconfig._set_tool("pybabel", "pybabel", pybabel_version)
+ return True
+ else:
+ # Has suffix, try suffix. We know the names in advance,
+ # so use a dictionary and iterate over it. Use enough names
+ # to safe updating this for another couple of years.
+ #
+ # Food for thought: If we only accept python 3.7 or higher,
+ # is checking pybabel + pybabel-3.[0-9]* too much and could
+ # be broken down to pybabel + pybabel-3.7 and later names?
+ version_dict = {
+ "3.0": "pybabel-3.0",
+ "3.1": "pybabel-3.1",
+ "3.2": "pybabel-3.2",
+ "3.3": "pybabel-3.3",
+ "3.4": "pybabel-3.4",
+ "3.5": "pybabel-3.5",
+ "3.6": "pybabel-3.6",
+ "3.7": "pybabel-3.7",
+ "3.8": "pybabel-3.8",
+ "3.9": "pybabel-3.9",
+ "4.0": "pybabel-4.0",
+ }
+ for key, value in version_dict.items():
+ if existence(value):
+ # FIXME: This version reporting is slightly off
+ # FIXME: and only maps to the suffix.
+ pybabel_version = key
+ buildconfig._set_tool("pybabel", value, pybabel_version)
+ return True
+
+
+class PythonTool(Tool):
+ # This exists in addition to the files in sh, so that
+ # the Makefiles can use this value instead.
+ name = "python"
+
+ def args(self, parser):
+ parser.add_argument(
+ "--with-python", type=str, help="name of the python executable"
+ )
+
+ def check(self, buildconfig):
+ # No suffix. Would probably be cheaper to do this in
+ # the dict as well. We need at least version 3.7.
+ if existence("python") and (shlex.split(subprocess.getstatusoutput("python --version")[1])[1] >= '3.7'):
+ # python might not be python3. It might not even be
+ # python 3.x.
+ python_version = shlex.split(subprocess.getstatusoutput("python --version")[1])[1]
+ if python_version >= '3.7':
+ buildconfig._set_tool("python", "python", python_version)
+ return True
+ else:
+ # Has suffix, try suffix. We know the names in advance,
+ # so use a dictionary and iterate over it. Use enough names
+ # to safe updating this for another couple of years.
+ #
+ # Food for thought: If we only accept python 3.7 or higher,
+ # is checking pybabel + pybabel-3.[0-9]* too much and could
+ # be broken down to pybabel + pybabel-3.7 and later names?
+ version_dict = {
+ "3.7": "python3.7",
+ "3.8": "python3.8",
+ "3.9": "python3.9",
+ "4.0": "python4.0",
+ }
+ for key, value in version_dict.items():
+ if existence(value):
+ python3_version = key
+ buildconfig._set_tool("python", value, python3_version)
+ return True
+
+
+# TODO: Make this really optional, not use a hack ("true").
+class BrowserTool(Tool):
+ name = "browser"
+
+ def args(self, parser):
+ parser.add_argument(
+ "--with-browser", type=str, help="name of your webbrowser executable"
+ )
+
+ def check(self, buildconfig):
+ browser_dict = {
+ "ice": "icecat",
+ "ff": "firefox",
+ "chg": "chrome",
+ "ch": "chromium",
+ "o": "opera",
+ "t": "true"
+ }
+ if "BROWSER" in os.environ:
+ buildconfig._set_tool("browser", os.environ["BROWSER"])
+ return True
+ for value in browser_dict.values():
+ if existence(value):
+ buildconfig._set_tool("browser", value)
+ return True
+
+
+class NodeJsTool(Tool):
+ name = "node"
+ hint = "If you are using Ubuntu Linux or Debian Linux, try installing the\nnode-legacy package or symlink node to nodejs."
+
+ def args(self, parser):
+ pass
+
+ def check(self, buildconfig):
+ if existence("node") is None:
+ return False
+ if (
+ subprocess.getstatusoutput(
+ "node -p 'process.exit(!(/v([0-9]+)/.exec(process.version)[1] >= 4))'"
+ )[1]
+ != ""
+ ):
+ buildconfig._warn("your node version is too old, use Node 4.x or newer")
+ return False
+ node_version = tool_version("node --version")
+ buildconfig._set_tool("node", "node", version=node_version)
+ return True
+
+
+class PosixTool(Tool):
+ def __init__(self, name):
+ self.name = name
+
+ def args(self, parser):
+ pass
+
+ def check(self, buildconfig):
+ found = existence("find")
+ if found:
+ buildconfig._set_tool(self.name, self.name)
+ return True
+ return False
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/build-common/testconfigure.py
^
|
@@ -0,0 +1,14 @@
+from talerbuildconfig import *
+
+b = BuildConfig()
+b.enable_prefix()
+b.enable_configmk()
+b.add_tool(YarnTool())
+b.add_tool(BrowserTool())
+b.add_tool(PyBabelTool())
+b.add_tool(NodeJsTool())
+b.add_tool(PythonTool())
+b.add_tool(PosixTool("find"))
+b.add_tool(PosixTool("xargs"))
+b.add_tool(PosixTool("msgmerge"))
+b.run()
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/gen_http_methods_insert.sh
^
|
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+#
+# Generate header insert for HTTP methods
+#
+
+# Copyright (c) 2015-2019 Karlson2k (Evgeny Grin) <k2k@yandex.ru>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+wget -nv http://www.iana.org/assignments/http-methods/methods.csv -O methods.csv || exit
+echo Generating...
+echo '/**
+ * @defgroup methods HTTP methods
+ * HTTP methods (as strings).
+ * See: http://www.iana.org/assignments/http-methods/http-methods.xml
+ * Registry export date: '$(date -u +%Y-%m-%d)'
+ * @{
+ */
+
+/* Main HTTP methods. */' > header_insert_methods.h && \
+gawk -e 'BEGIN {FPAT = "([^,]*)|(\"[^\"]+\")"}
+FNR > 1 {
+ gsub(/^\[|^"\[|\]"$|\]$/, "", $4)
+ gsub(/\]\[/, "; ", $4)
+ if (substr($4, 1, 7) == "RFC7231") {
+ if ($2 == "yes")
+ { safe_m = "Safe. " }
+ else
+ { safe_m = "Not safe." }
+ if ($3 == "yes")
+ { indem_m = "Idempotent. " }
+ else
+ { indem_m = "Not idempotent." }
+ print "/* " safe_m " " indem_m " " $4 ". */"
+ print "#define MHD_HTTP_METHOD_" toupper(gensub(/-/, "_", "g", $1)) " \""$1"\""
+ }
+}' methods.csv >> header_insert_methods.h && \
+echo '
+/* Additional HTTP methods. */' >> header_insert_methods.h && \
+gawk -e 'BEGIN {FPAT = "([^,]*)|(\"[^\"]+\")"}
+FNR > 1 {
+ gsub(/^\[|^"\[|\]"$|\]$/, "", $4)
+ gsub(/\]\[/, "; ", $4)
+ if (substr($4, 1, 7) != "RFC7231") {
+ if ($2 == "yes")
+ { safe_m = "Safe. " }
+ else
+ { safe_m = "Not safe." }
+ if ($3 == "yes")
+ { indem_m = "Idempotent. " }
+ else
+ { indem_m = "Not idempotent." }
+ print "/* " safe_m " " indem_m " " $4 ". */"
+ print "#define MHD_HTTP_METHOD_" toupper(gensub(/-/, "_", "g", $1)) " \""$1"\""
+ }
+}' methods.csv >> header_insert_methods.h && \
+echo OK && \
+rm methods.csv || exit
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/gen_http_statuses_inserts.sh
^
|
@@ -0,0 +1,100 @@
+#!/bin/bash
+
+#
+# Generate code and header inserts for HTTP statues
+#
+
+# Copyright (c) 2019 Karlson2k (Evgeny Grin) <k2k@yandex.ru>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+wget -nv https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv -O http-status-codes-1.csv || exit
+echo Generating...
+echo "/**
+ * @defgroup httpcode HTTP response codes.
+ * These are the status codes defined for HTTP responses.
+ * See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * Registry export date: $(date -u +%Y-%m-%d)
+ * @{
+ */
+" > header_insert_statuses.h && \
+gawk -e 'BEGIN {FPAT = "([^,]*)|(\"[^\"]+\")"}
+FNR > 1 {
+ gsub(/^\[|^"\[|\]"$|\]$/, "", $3)
+ gsub(/\]\[/, "; ", $3)
+ if ($1 == 306) {
+ $2 = "Switch Proxy"
+ $3 = "Not used! " $3
+ }
+ if ($2 != "Unassigned") {
+ print "/* " $1 sprintf("%-24s", " \"" $2 "\". ") $3 ". */"
+ print "#define MHD_HTTP_" toupper(gensub(/[^A-Za-z0-0]/, "_", "g", $2)) " "$1""
+ } else {
+ print ""
+ }
+}' http-status-codes-1.csv >> header_insert_statuses.h && \
+echo '
+/* Not registered non-standard codes */
+/* 449 "Reply With". MS IIS extension. */
+#define MHD_HTTP_RETRY_WITH 449
+
+/* 450 "Blocked by Windows Parental Controls". MS extension. */
+#define MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450
+
+/* 509 "Bandwidth Limit Exceeded". Apache extension. */
+#define MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509
+' >> header_insert_statuses.h && \
+gawk -e 'BEGIN {
+ FPAT = "([^,]*)|(\"[^\"]+\")"
+ hundreds[1]="one"
+ hundreds[2]="two"
+ hundreds[3]="three"
+ hundreds[4]="four"
+ hundreds[5]="five"
+ hundreds[6]="six"
+ prev_num=0
+ prev_reason=""
+ prev_desc=""
+ num=0
+ reason=""
+ desc=""
+}
+FNR > 1 {
+ gsub(/^\[|^"\[|\]"$|\]$/, "", $3)
+ gsub(/\]\[/, "; ", $3)
+ num = $1
+ reason = $2
+ desc = $3
+ if (num % 100 == 0) {
+ if (num != 100) {
+ printf (" /* %s */ %-24s /* %s */\n};\n\n", prev_num, "\""prev_reason"\"", prev_desc)
+ }
+ prev_num = num;
+ print "static const char *const " hundreds[$1/100] "_hundred[] = {"
+ }
+ if (num == 306) {
+ reason = "Switch Proxy"
+ desc = "Not used! " desc
+ }
+ if (reason == "Unassigned") next
+ if (prev_num != num)
+ printf (" /* %s */ %-24s /* %s */\n", prev_num, "\""prev_reason"\",", prev_desc)
+ while(++prev_num < num) {
+ if (prev_num == 449) {prev_reason="Reply With"; prev_desc="MS IIS extension";}
+ else if (prev_num == 450) {prev_reason="Blocked by Windows Parental Controls"; prev_desc="MS extension";}
+ else if (prev_num == 509) {prev_reason="Bandwidth Limit Exceeded"; prev_desc="Apache extension";}
+ else {prev_reason="Unknown"; prev_desc="Not used";}
+ printf (" /* %s */ %-24s /* %s */\n", prev_num, "\""prev_reason"\",", prev_desc)
+ }
+ prev_num = num
+ prev_reason = reason
+ prev_desc = desc
+}
+END {
+ printf (" /* %s */ %-24s /* %s */\n};\n", prev_num, "\""prev_reason"\"", prev_desc)
+}' http-status-codes-1.csv > code_insert_statuses.c && \
+echo OK && \
+rm http-status-codes-1.csv || exit
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/uncrustify.cfg
^
|
@@ -0,0 +1,111 @@
+input_tab_size = 2
+output_tab_size = 2
+
+indent_columns = 2
+indent_with_tabs = 0
+indent_case_brace = 2
+indent_label=-16
+
+code_width=80
+#cmd_width=80
+
+# Leave most comments alone for now
+cmt_indent_multi=false
+sp_cmt_cpp_start=add
+
+sp_not=add
+
+sp_func_call_user_paren_paren=remove
+sp_inside_fparen=remove
+sp_after_cast=add
+
+ls_for_split_full=true
+ls_func_split_full=true
+ls_code_width=true
+
+# Arithmetic operations in wrapped expressions should be at the start
+# of the line.
+pos_arith=lead
+
+# Fully parenthesize boolean exprs
+mod_full_paren_if_bool=true
+
+# Braces should be on their own line
+nl_fdef_brace=add
+nl_enum_brace=add
+nl_struct_brace=add
+nl_union_brace=add
+nl_if_brace=add
+nl_brace_else=add
+nl_elseif_brace=add
+nl_while_brace=add
+nl_switch_brace=add
+
+# no newline between "else" and "if"
+nl_else_if=remove
+
+nl_func_paren=remove
+nl_assign_brace=remove
+
+# No extra newlines that cause noisy diffs
+nl_start_of_file=remove
+nl_after_func_proto = 2
+nl_after_func_body = 3
+# If there's no new line, it's not a text file!
+nl_end_of_file=add
+nl_max_blank_in_func = 3
+nl_max = 3
+
+sp_inside_paren = remove
+
+sp_arith = add
+sp_arith_additive = add
+
+# We want spaces before and after "="
+sp_before_assign = add
+sp_after_assign = add
+
+# we want "char *foo;"
+sp_after_ptr_star = remove
+sp_between_ptr_star = remove
+
+# we want "if (foo) { ... }"
+sp_before_sparen = add
+
+sp_inside_fparen = remove
+sp_inside_sparen = remove
+
+# add space before function call and decl: "foo (x)"
+sp_func_call_paren = add
+sp_func_proto_paren = add
+sp_func_proto_paren_empty = add
+sp_func_def_paren = add
+sp_func_def_paren_empty = add
+
+# We'd want it for "if ( (foo) || (bar) )", but not for "if (m())",
+# so as uncrustify doesn't give exactly what we want => ignore
+sp_paren_paren = ignore
+sp_inside_paren = remove
+sp_bool = force
+
+nl_func_type_name = force
+#nl_branch_else = add
+nl_else_brace = add
+nl_elseif_brace = add
+nl_for_brace = add
+
+# Whether to ignore the '#define' body while formatting.
+pp_ignore_define_body = true # true/false
+
+# Add or remove space between #else or #endif and a trailing comment.
+sp_endif_cmt = add # ignore/add/remove/force
+
+# The span for aligning comments that end lines.
+#
+# 0: Don't align (default).
+align_right_cmt_span = 3 # unsigned number
+
+# Minimum number of columns between preceding text and a trailing comment in
+# order for the comment to qualify for being aligned. Must be non-zero to have
+# an effect.
+align_right_cmt_gap = 2 # unsigned number
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/uncrustify.sh
^
|
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -eu
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+if ! uncrustify --version >/dev/null; then
+ echo "you need to install uncrustify for indentation"
+ exit 1
+fi
+
+find "$DIR/../src" \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) \
+ -exec uncrustify -c "$DIR/uncrustify.cfg" --replace --no-backup {} + \
+ || true
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/contrib/uncrustify_precommit
^
|
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# use as .git/hooks/pre-commit
+
+exec 1>&2
+
+RET=0
+changed=$(git diff --cached --name-only)
+crustified=""
+
+for f in $changed;
+do
+ if echo $f | grep \\.[c,h]\$ > /dev/null
+ then
+ # compare result of uncrustify with changes
+ #
+ # only change any of the invocations here if
+ # they are portable across all cmp and shell
+ # implementations !
+ uncrustify -q -c uncrustify.cfg -f $f | cmp -s $f -
+ if test $? = 1 ;
+ then
+ crustified=" $crustified $f"
+ RET=1
+ fi
+ fi
+done
+
+if [ $RET = 1 ];
+then
+ echo "Run"
+ echo "uncrustify --no-backup -c uncrustify.cfg ${crustified}"
+ echo "before committing."
+fi
+exit $RET
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/.gitignore
^
|
@@ -25,19 +25,20 @@
/microhttpd-tutorial.fn
/microhttpd-tutorial.cp
/microhttpd-tutorial.aux
-/tutorial.vr
-/tutorial.tp
-/tutorial.pg
-/tutorial.pdf
-/tutorial.log
-/tutorial.ky
-/tutorial.html
-/tutorial.fn
-/tutorial.cp
+/libmicrohttpd-tutorial.vr
+/libmicrohttpd-tutorial.tp
+/libmicrohttpd-tutorial.pg
+/libmicrohttpd-tutorial.pdf
+/libmicrohttpd-tutorial.log
+/libmicrohttpd-tutorial.ky
+/libmicrohttpd-tutorial.html
+/libmicrohttpd-tutorial.fn
+/libmicrohttpd-tutorial.cp
+/libmicrohttpd-tutorial.cps
/microhttpd.html
/version.texi.orig
-/tutorial.toc
-/tutorial.aux
+/libmicrohttpd-tutorial.toc
+/libmicrohttpd-tutorial.aux
/stamp-vti.orig
/microhttpd.info.orig
/microhttpd.vr
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/Makefile.am
^
|
@@ -12,6 +12,7 @@
libmicrohttpd.dvi \
libmicrohttpd-tutorial.cps \
libmicrohttpd-tutorial.dvi
+
info_TEXINFOS = \
libmicrohttpd.texi \
libmicrohttpd-tutorial.texi
@@ -27,11 +28,34 @@
chapters/tlsauthentication.inc \
chapters/sessions.inc \
fdl-1.3.texi \
+ gpl-2.0.texi \
lgpl.texi \
ecos.texi
EXTRA_DIST = \
$(man_MANS) \
$(microhttpd_TEXINFOS) \
- performance_data.png \
- performance_data.eps
+ libmicrohttpd_performance_data.png \
+ libmicrohttpd_performance_data.eps
+
+install-info-local:
+ @echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ echo " $(INSTALL_DATA) libmicrohttpd_performance_data.png '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $(srcdir)/libmicrohttpd_performance_data.png "$(DESTDIR)$(infodir)" || exit 1;
+
+install-html-local:
+ @if test -n "$(htmldir)"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/libmicrohttpd.html'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/libmicrohttpd.html" || exit 1; \
+ echo " $(INSTALL_DATA) libmicrohttpd_performance_data.png '$(DESTDIR)$(htmldir)/libmicrohttpd.html'"; \
+ $(INSTALL_DATA) $(srcdir)/libmicrohttpd_performance_data.png "$(DESTDIR)$(htmldir)/libmicrohttpd.html" || exit 1; \
+ else : ; fi
+
+uninstall-local:
+ @if test -d "$(DESTDIR)$(infodir)"; then \
+ echo " rm -f '$(DESTDIR)$(infodir)/libmicrohttpd_performance_data.png'"; \
+ rm -f "$(DESTDIR)$(infodir)/libmicrohttpd_performance_data.png" \
+ else : ; fi
+
+# end of 'if BUILD_DOC'
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/chapters/basicauthentication.inc
^
|
@@ -1,7 +1,7 @@
-With the small exception of IP address based access control,
+With the small exception of IP address based access control,
requests from all connecting clients where served equally until now.
This chapter discusses a first method of client's authentication and
-its limits.
+its limits.
A very simple approach feasible with the means already discussed would
be to expect the password in the @emph{URI} string before granting access to
@@ -12,68 +12,102 @@
@end verbatim
@noindent
-In the rare situation where the client is customized enough and the connection occurs
-through secured lines (e.g., a embedded device directly attached to another via wire)
-and where the ability to embedd a password in the URI or to pass on a URI with a
-password are desired, this can be a reasonable choice.
-
-But when it is assumed that the user connecting does so with an ordinary Internet browser,
-this implementation brings some problems about. For example, the URI including the password
-stays in the address field or at least in the history of the browser for anybody near enough to see.
-It will also be inconvenient to add the password manually to any new URI when the browser does
+In the rare situation where the client is customized enough and the connection
+occurs through secured lines (e.g., a embedded device directly attached to
+another via wire) and where the ability to embed a password in the URI or to
+pass on a URI with a password are desired, this can be a reasonable choice.
+
+But when it is assumed that the user connecting does so with an ordinary
+Internet browser, this implementation brings some problems about. For example,
+the URI including the password stays in the address field or at least in the
+history of the browser for anybody near enough to see. It will also be
+inconvenient to add the password manually to any new URI when the browser does
not know how to compose this automatically.
-At least the convenience issue can be addressed by employing the simplest built-in password
-facilities of HTTP compliant browsers, hence we want to start there. It will however turn out
-to have still severe weaknesses in terms of security which need consideration.
-
-Before we will start implementing @emph{Basic Authentication} as described in @emph{RFC 2617},
-we should finally abandon the bad practice of responding every request the first time our callback
-is called for a given connection. This is becoming more important now because the client and
-the server will have to talk in a more bi-directional way than before to
-
-But how can we tell whether the callback has been called before for the particular connection?
-Initially, the pointer this parameter references is set by @emph{MHD} in the callback. But it will
-also be "remembered" on the next call (for the same connection).
-Thus, we will generate no response until the parameter is non-null---implying the callback was
-called before at least once. We do not need to share information between different calls of the callback,
-so we can set the parameter to any adress that is assured to be not null. The pointer to the
-@code{connection} structure will be pointing to a legal address, so we take this.
+At least the convenience issue can be addressed by employing the simplest
+built-in password facilities of HTTP compliant browsers, hence we want to
+start there. It will, however, turn out to have still severe weaknesses in
+terms of security which need consideration.
+
+Before we will start implementing @emph{Basic Authentication} as described in
+@emph{RFC 2617}, we will also abandon the simplistic and generally
+problematic practice of responding every request the first time our callback
+is called for a given connection. Queuing a response upon the first request
+is akin to generating an error response (even if it is a "200 OK" reply!).
+The reason is that MHD usually calls the callback in three phases:
+
+@enumerate
+@item
+First, to initially tell the application about the connection and inquire whether
+it is OK to proceed. This call typically happens before the client could upload
+the request body, and can be used to tell the client to not proceed with the
+upload (if the client requested "Expect: 100 Continue"). Applications may queue
+a reply at this point, but it will force the connection to be closed and thus
+prevent keep-alive / pipelining, which is generally a bad idea. Applications
+wanting to proceed with the request throughout the other phases should just return
+"MHD_YES" and not queue any response. Note that when an application suspends
+a connection in this callback, the phase does not advance and the application
+will be called again in this first phase.
+@item
+Next, to tell the application about upload data provided by the client.
+In this phase, the application may not queue replies, and trying to do so
+will result in MHD returning an error code from @code{MHD_queue_response}.
+If there is no upload data, this phase is skipped.
+@item
+Finally, to obtain a regular response from the application. This can be
+almost any type of response, including ones indicating failures. The
+one exception is a "100 Continue" response, which applications must never
+generate: MHD generates that response automatically when necessary in the
+first phase. If the application does not queue a response, MHD may call
+the callback repeatedly (depending a bit on the threading model, the
+application should suspend the connection).
+@end enumerate
+
+But how can we tell whether the callback has been called before for the
+particular connection? Initially, the pointer this parameter references is
+set by @emph{MHD} in the callback. But it will also be "remembered" on the
+next call (for the same connection). Thus, we can use the @code{con_cls}
+location to keep track of the connection state. For now, we will simply
+generate no response until the parameter is non-null---implying the callback
+was called before at least once. We do not need to share information between
+different calls of the callback, so we can set the parameter to any address
+that is assured to be not null. The pointer to the @code{connection} structure
+will be pointing to a legal address, so we take this.
The first time @code{answer_to_connection} is called, we will not even look at the headers.
@verbatim
-static int
+static int
answer_to_connection (void *cls, struct MHD_Connection *connection,
- const char *url, const char *method, const char *version,
+ const char *url, const char *method, const char *version,
const char *upload_data, size_t *upload_data_size,
void **con_cls)
{
if (0 != strcmp(method, "GET")) return MHD_NO;
if (NULL == *con_cls) {*con_cls = connection; return MHD_YES;}
- ...
+ ...
/* else respond accordingly */
...
}
@end verbatim
@noindent
-Note how we lop off the connection on the first condition (no "GET" request), but return asking for more on
-the other one with @code{MHD_YES}.
-With this minor change, we can proceed to implement the actual authentication process.
-
-@heading Request for authentication
-
-Let us assume we had only files not intended to be handed out without the correct username/password,
-so every "GET" request will be challenged.
-@emph{RFC 2617} describes how the server shall ask for authentication by adding a
-@emph{WWW-Authenticate} response header with the name of the @emph{realm} protected.
-MHD can generate and queue such a failure response for you using
-the @code{MHD_queue_basic_auth_fail_response} API. The only thing you need to do
-is construct a response with the error page to be shown to the user
-if he aborts basic authentication. But first, you should check if the
-proper credentials were already supplied using the
+Note how we lop off the connection on the first condition (no "GET" request),
+but return asking for more on the other one with @code{MHD_YES}. With this
+minor change, we can proceed to implement the actual authentication process.
+
+@heading Request for authentication
+
+Let us assume we had only files not intended to be handed out without the
+correct username/password, so every "GET" request will be challenged.
+@emph{RFC 2617} describes how the server shall ask for authentication by
+adding a @emph{WWW-Authenticate} response header with the name of the
+@emph{realm} protected. MHD can generate and queue such a failure response
+for you using the @code{MHD_queue_basic_auth_fail_response} API. The only
+thing you need to do is construct a response with the error page to be shown
+to the user if he aborts basic authentication. But first, you should check if
+the proper credentials were already supplied using the
@code{MHD_basic_auth_get_username_password} call.
Your code would then look like this:
@@ -87,6 +121,7 @@
char *user;
char *pass;
int fail;
+ enum MHD_Result ret;
struct MHD_Response *response;
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
@@ -100,14 +135,14 @@
user = MHD_basic_auth_get_username_password (connection, &pass);
fail = ( (user == NULL) ||
(0 != strcmp (user, "root")) ||
- (0 != strcmp (pass, "pa$$w0rd") ) );
+ (0 != strcmp (pass, "pa$$w0rd") ) );
if (user != NULL) free (user);
if (pass != NULL) free (pass);
if (fail)
{
const char *page = "<html><body>Go away.</body></html>";
response =
- MHD_create_response_from_buffer (strlen (page), (void *) page,
+ MHD_create_response_from_buffer (strlen (page), (void *) page,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_basic_auth_fail_response (connection,
"my realm",
@@ -117,7 +152,7 @@
{
const char *page = "<html><body>A secret.</body></html>";
response =
- MHD_create_response_from_buffer (strlen (page), (void *) page,
+ MHD_create_response_from_buffer (strlen (page), (void *) page,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
}
@@ -129,9 +164,9 @@
See the @code{examples} directory for the complete example file.
@heading Remarks
-For a proper server, the conditional statements leading to a return of @code{MHD_NO} should yield a
+For a proper server, the conditional statements leading to a return of @code{MHD_NO} should yield a
response with a more precise status code instead of silently closing the connection. For example,
-failures of memory allocation are best reported as @emph{internal server error} and unexpected
+failures of memory allocation are best reported as @emph{internal server error} and unexpected
authentication methods as @emph{400 bad request}.
@heading Exercises
@@ -141,7 +176,7 @@
@emph{401 unauthorized} status code. If the client still does not authenticate correctly within the
same connection, close it and store the client's IP address for a certain time. (It is OK to check for
expiration not until the main thread wakes up again on the next connection.) If the client fails
-authenticating three times during this period, add it to another list for which the
+authenticating three times during this period, add it to another list for which the
@code{AcceptPolicyCallback} function denies connection (temporally).
@item
@@ -155,5 +190,3 @@
and see how both the user's name and password could be completely restored.
@end itemize
-
-
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/chapters/hellobrowser.inc
^
|
@@ -29,7 +29,7 @@
appropriate request comes in. While the name of this callback function is arbitrary, its parameter
list has to follow a certain layout. So please, ignore the lot of parameters for now, they will be
explained at the point they are needed. We have to use only one of them,
-@code{struct MHD_Connection *connection}, for the minimalistic functionality we want to archive at the moment.
+@code{struct MHD_Connection *connection}, for the minimalistic functionality we want to achieve at the moment.
This parameter is set by the @emph{libmicrohttpd} daemon and holds the necessary information to
relate the call with a certain connection. Keep in mind that a server might have to satisfy hundreds
@@ -116,7 +116,7 @@
we do not need to pass extra options to the daemon so we just write the MHD_OPTION_END as the last parameter.
As the server daemon runs in the background in its own thread, the execution flow in our main
-function will contine right after the call. Because of this, we must delay the execution flow in the
+function will continue right after the call. Because of this, we must delay the execution flow in the
main thread or else the program will terminate prematurely. We let it pause in a processing-time
friendly manner by waiting for the enter key to be pressed. In the end, we stop the daemon so it can
do its cleanup tasks.
@@ -161,7 +161,7 @@
disables HTTP pipelining. The correct approach is to simply not queue a message on the first
callback unless there is an error. The @code{void**} argument to the callback provides a location
for storing information about the history of the connection; for the first call, the pointer
-will point to NULL. A simplistic way to differenciate the first call from others is to check
+will point to NULL. A simplistic way to differentiate the first call from others is to check
if the pointer is NULL and set it to a non-NULL value during the first call.
Both of these issues you will find addressed in the official @code{minimal_example.c} residing in
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/chapters/introduction.inc
^
|
@@ -19,5 +19,5 @@
@section History
This tutorial was originally written by Sebastian Gerhardt for MHD
-0.4.0. It was slighly polished and updated to MHD 0.9.0 by Christian
+0.4.0. It was slightly polished and updated to MHD 0.9.0 by Christian
Grothoff.
\ No newline at end of file
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/chapters/largerpost.inc
^
|
@@ -49,7 +49,7 @@
adequately.
@verbatim
const char* servererrorpage
- = "<html><body>An internal server error has occured.</body></html>";
+ = "<html><body>An internal server error has occurred.</body></html>";
const char* fileexistspage
= "<html><body>This file already exists.</body></html>";
@end verbatim
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/chapters/tlsauthentication.inc
^
|
@@ -65,7 +65,7 @@
@end verbatim
@noindent
-and then we point the @emph{MHD} daemon to it upon initalization.
+and then we point the @emph{MHD} daemon to it upon initialization.
@verbatim
daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_SSL,
@@ -161,7 +161,7 @@
ci = MHD_get_connection_info (connection,
MHD_CONNECTION_INFO_GNUTLS_SESSION);
-tls_session = ci->tls_session;
+tls_session = (gnutls_session_t) ci->tls_session;
@end verbatim
You can then extract the client certificate:
@@ -187,6 +187,13 @@
if (gnutls_certificate_verify_peers2(tls_session,
&client_cert_status))
return NULL;
+ if (0 != client_cert_status)
+ {
+ fprintf (stderr,
+ "Failed client certificate invalid: %d\n",
+ client_cert_status);
+ return NULL;
+ }
pcert = gnutls_certificate_get_peers(tls_session,
&listsize);
if ( (pcert == NULL) ||
@@ -229,7 +236,7 @@
* to the dn if found
*/
char *
-cert_auth_get_dn(gnutls_x509_crt_c client_cert)
+cert_auth_get_dn(gnutls_x509_crt_t client_cert)
{
char* buf;
size_t lbuf;
@@ -421,7 +428,7 @@
point.
The @code{hosts} list can be initialized by loading the private keys and X.509
-certificats from disk as follows:
+certificates from disk as follows:
@verbatim
static void
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/doxygen/libmicrohttpd.doxy.in
^
|
@@ -0,0 +1,2464 @@
+# Doxyfile 1.8.13
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "GNU libmicrohttpd"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = @PACKAGE_VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = .
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = YES
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH = ../..
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH = ../../src/include \
+ src/include
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = ../..
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.c \
+ *.h
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */test_* \
+ */.svn/* \
+ */perf_* \
+ */tls_test_* \
+ */examples/* \
+ */testcurl/* \
+ */testzzuf/* \
+ */platform/* \
+ */symbian/* \
+ MHD_config.h \
+ microhttpd2.h
+
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS = MHD_DLOG
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = NO
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: YES.
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = NO
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = YES
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = NO
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 25
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 2
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/ecos.texi
^
|
@@ -1,405 +1,26 @@
-@cindex GPL, GNU General Public License
@cindex eCos, GNU General Public License with eCos Extension
-@center Version 2, June 1991
-@display
-Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+GNU libmicrohttpd is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 or (at your option) any later version.
+
+GNU libmicrohttpd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+You should have received a copy of the GNU General Public License along with
+GNU libmicrohttpd; if not, write to the Free Software Foundation, Inc., 51
+Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+As a special exception, if other files instantiate templates or use macros or
+inline functions from this file, or you compile this file and link it with
+other works to produce a work based on this file, this file does not by itself
+cause the resulting work to be covered by the GNU General Public
+License. However the source code for this file must still be made available in
+accordance with section (3) of the GNU General Public License v2.
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-@end display
+This exception does not invalidate any other reasons why a work based on this
+file might be covered by the GNU General Public License.
-
-
-@subheading Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software---to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
-@iftex
-@subheading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end iftex
-@ifinfo
-@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end ifinfo
-
-@enumerate
-@item
-This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The ``Program'', below,
-refers to any such program or work, and a ``work based on the Program''
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term ``modification''.) Each licensee is addressed as ``you''.
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-@item
-You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-@item
-You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-@enumerate a
-@item
-You must cause the modified files to carry prominent notices
-stating that you changed the files and the date of any change.
-
-@item
-You must cause any work that you distribute or publish, that in
-whole or in part contains or is derived from the Program or any
-part thereof, to be licensed as a whole at no charge to all third
-parties under the terms of this License.
-
-@item
-If the modified program normally reads commands interactively
-when run, you must cause it, when started running for such
-interactive use in the most ordinary way, to print or display an
-announcement including an appropriate copyright notice and a
-notice that there is no warranty (or else, saying that you provide
-a warranty) and that users may redistribute the program under
-these conditions, and telling the user how to view a copy of this
-License. (Exception: if the Program itself is interactive but
-does not normally print such an announcement, your work based on
-the Program is not required to print an announcement.)
-@end enumerate
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-@item
-You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-@enumerate a
-@item
-Accompany it with the complete corresponding machine-readable
-source code, which must be distributed under the terms of Sections
-1 and 2 above on a medium customarily used for software interchange; or,
-
-@item
-Accompany it with a written offer, valid for at least three
-years, to give any third party, for a charge no more than your
-cost of physically performing source distribution, a complete
-machine-readable copy of the corresponding source code, to be
-distributed under the terms of Sections 1 and 2 above on a medium
-customarily used for software interchange; or,
-
-@item
-Accompany it with the information you received as to the offer
-to distribute corresponding source code. (This alternative is
-allowed only for noncommercial distribution and only if you
-received the program in object code or executable form with such
-an offer, in accord with Subsection b above.)
-@end enumerate
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-@item
-You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-@item
-You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-@item
-Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-@item
-If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-@item
-If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-@item
-The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and ``any
-later version'', you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-@item
-If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-@center @b{NO WARRANTY}
-
-@item
-BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-@item
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-@center @b{ECOS EXTENSION}
-
-
-@item
-As a special exception, if other files instantiate templates or use
-macros or inline functions from this file, or you compile this file
-and link it with other works to produce a work based on this file,
-this file does not by itself cause the resulting work to be covered by
-the GNU General Public License. However the source code for this file
-must still be made available in accordance with section (3) of the GNU
-General Public License v2.
-
-This exception does not invalidate any other reasons why a work based
-on this file might be covered by the GNU General Public License.
-
-@end enumerate
-
-
-@subheading END OF TERMS AND CONDITIONS
-
-@page
-@unnumberedsec How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the ``copyright'' line and a pointer to where the full notice is found.
-
-@smallexample
-@var{one line to give the program's name and an idea of what it does.}
-Copyright (C) 19@var{yy} @var{name of author}
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-@end smallexample
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-@smallexample
-Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
-Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
-type `show w'. This is free software, and you are welcome
-to redistribute it under certain conditions; type `show c'
-for details.
-@end smallexample
-
-The hypothetical commands @samp{show w} and @samp{show c} should show
-the appropriate parts of the General Public License. Of course, the
-commands you use may be called something other than @samp{show w} and
-@samp{show c}; they could even be mouse-clicks or menu items---whatever
-suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a ``copyright disclaimer'' for the program, if
-necessary. Here is a sample; alter the names:
-
-@smallexample
-@group
-Yoyodyne, Inc., hereby disclaims all copyright
-interest in the program `Gnomovision'
-(which makes passes at compilers) written
-by James Hacker.
-
-@var{signature of Ty Coon}, 1 April 1989
-Ty Coon, President of Vice
-@end group
-@end smallexample
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/Makefile.am
^
|
@@ -12,10 +12,14 @@
# example programs
noinst_PROGRAMS = \
- basicauthentication \
hellobrowser \
logging \
- responseheaders
+ responseheaders
+
+if ENABLE_BAUTH
+noinst_PROGRAMS += \
+ basicauthentication
+endif
if ENABLE_HTTPS
noinst_PROGRAMS += \
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/basicauthentication.c
^
|
@@ -17,7 +17,7 @@
#define PORT 8888
-static int
+static enum MHD_Result
answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
@@ -26,48 +26,56 @@
char *user;
char *pass;
int fail;
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO;
if (NULL == *con_cls)
- {
- *con_cls = connection;
- return MHD_YES;
- }
+ {
+ *con_cls = connection;
+ return MHD_YES;
+ }
pass = NULL;
- user = MHD_basic_auth_get_username_password (connection, &pass);
- fail = ( (user == NULL) ||
- (0 != strcmp (user, "root")) ||
- (0 != strcmp (pass, "pa$$w0rd") ) );
- if (user != NULL) free (user);
- if (pass != NULL) free (pass);
+ user = MHD_basic_auth_get_username_password (connection,
+ &pass);
+ fail = ( (NULL == user) ||
+ (0 != strcmp (user, "root")) ||
+ (0 != strcmp (pass, "pa$$w0rd") ) );
+ if (NULL != user)
+ MHD_free (user);
+ if (NULL != pass)
+ MHD_free (pass);
if (fail)
- {
- const char *page = "<html><body>Go away.</body></html>";
- response =
- MHD_create_response_from_buffer (strlen (page), (void *) page,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_basic_auth_fail_response (connection,
- "my realm",
- response);
- }
+ {
+ const char *page = "<html><body>Go away.</body></html>";
+ response =
+ MHD_create_response_from_buffer (strlen (page), (void *) page,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_basic_auth_fail_response (connection,
+ "my realm",
+ response);
+ }
else
- {
- const char *page = "<html><body>A secret.</body></html>";
- response =
- MHD_create_response_from_buffer (strlen (page), (void *) page,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- }
+ {
+ const char *page = "<html><body>A secret.</body></html>";
+ response =
+ MHD_create_response_from_buffer (strlen (page), (void *) page,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ }
MHD_destroy_response (response);
return ret;
}
int
-main ()
+main (void)
{
struct MHD_Daemon *daemon;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/hellobrowser.c
^
|
@@ -14,7 +14,7 @@
#define PORT 8888
-static int
+static enum MHD_Result
answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
@@ -22,11 +22,18 @@
{
const char *page = "<html><body>Hello, browser!</body></html>";
struct MHD_Response *response;
- int ret;
-
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) method; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) con_cls; /* Unused. Silent compiler warning. */
+
response =
- MHD_create_response_from_buffer (strlen (page), (void *) page,
- MHD_RESPMEM_PERSISTENT);
+ MHD_create_response_from_buffer (strlen (page), (void *) page,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
@@ -35,11 +42,12 @@
int
-main ()
+main (void)
{
struct MHD_Daemon *daemon;
- daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
+ daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ PORT, NULL, NULL,
&answer_to_connection, NULL, MHD_OPTION_END);
if (NULL == daemon)
return 1;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/largepost.c
^
|
@@ -15,11 +15,11 @@
#ifdef _MSC_VER
#ifndef strcasecmp
-#define strcasecmp(a,b) _stricmp((a),(b))
+#define strcasecmp(a,b) _stricmp ((a),(b))
#endif /* !strcasecmp */
#endif /* _MSC_VER */
-#if defined(_MSC_VER) && _MSC_VER+0 <= 1800
+#if defined(_MSC_VER) && _MSC_VER + 0 <= 1800
/* Substitution is OK while return value is not used */
#define snprintf _snprintf
#endif
@@ -29,10 +29,10 @@
#define MAXCLIENTS 2
enum ConnectionType
- {
- GET = 0,
- POST = 1
- };
+{
+ GET = 0,
+ POST = 1
+};
static unsigned int nr_of_uploading_clients = 0;
@@ -66,7 +66,8 @@
};
-const char *askpage = "<html><body>\n\
+const char *askpage =
+ "<html><body>\n\
Upload a file, please!<br>\n\
There are %u clients uploading at the moment.<br>\n\
<form action=\"/filepost\" method=\"post\" enctype=\"multipart/form-data\">\n\
@@ -85,23 +86,23 @@
"<html><body>This file already exists.</body></html>";
const char *fileioerror =
"<html><body>IO error writing to disk.</body></html>";
-const char* const postprocerror =
+const char*const postprocerror =
"<html><head><title>Error</title></head><body>Error processing POST data</body></html>";
-static int
+static enum MHD_Result
send_page (struct MHD_Connection *connection,
const char *page,
int status_code)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
response =
MHD_create_response_from_buffer (strlen (page),
(void *) page,
- MHD_RESPMEM_MUST_COPY);
- if (!response)
+ MHD_RESPMEM_MUST_COPY);
+ if (! response)
return MHD_NO;
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -115,7 +116,7 @@
}
-static int
+static enum MHD_Result
iterate_post (void *coninfo_cls,
enum MHD_ValueKind kind,
const char *key,
@@ -128,44 +129,50 @@
{
struct connection_info_struct *con_info = coninfo_cls;
FILE *fp;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
+ (void) off; /* Unused. Silent compiler warning. */
if (0 != strcmp (key, "file"))
+ {
+ con_info->answerstring = servererrorpage;
+ con_info->answercode = MHD_HTTP_BAD_REQUEST;
+ return MHD_YES;
+ }
+
+ if (! con_info->fp)
+ {
+ if (0 != con_info->answercode) /* something went wrong */
+ return MHD_YES;
+ if (NULL != (fp = fopen (filename, "rb")))
{
- con_info->answerstring = servererrorpage;
- con_info->answercode = MHD_HTTP_BAD_REQUEST;
+ fclose (fp);
+ con_info->answerstring = fileexistspage;
+ con_info->answercode = MHD_HTTP_FORBIDDEN;
return MHD_YES;
}
-
- if (! con_info->fp)
+ /* NOTE: This is technically a race with the 'fopen()' above,
+ but there is no easy fix, short of moving to open(O_EXCL)
+ instead of using fopen(). For the example, we do not care. */
+ con_info->fp = fopen (filename, "ab");
+ if (! con_info->fp)
{
- if (0 != con_info->answercode) /* something went wrong */
- return MHD_YES;
- if (NULL != (fp = fopen (filename, "rb")))
- {
- fclose (fp);
- con_info->answerstring = fileexistspage;
- con_info->answercode = MHD_HTTP_FORBIDDEN;
- return MHD_YES;
- }
-
- con_info->fp = fopen (filename, "ab");
- if (!con_info->fp)
- {
- con_info->answerstring = fileioerror;
- con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
- return MHD_YES;
- }
+ con_info->answerstring = fileioerror;
+ con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ return MHD_YES;
}
+ }
if (size > 0)
+ {
+ if (! fwrite (data, sizeof (char), size, con_info->fp))
{
- if (! fwrite (data, sizeof (char), size, con_info->fp))
- {
- con_info->answerstring = fileioerror;
- con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
- return MHD_YES;
- }
+ con_info->answerstring = fileioerror;
+ con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ return MHD_YES;
}
+ }
return MHD_YES;
}
@@ -178,28 +185,31 @@
enum MHD_RequestTerminationCode toe)
{
struct connection_info_struct *con_info = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == con_info)
return;
if (con_info->connectiontype == POST)
+ {
+ if (NULL != con_info->postprocessor)
{
- if (NULL != con_info->postprocessor)
- {
- MHD_destroy_post_processor (con_info->postprocessor);
- nr_of_uploading_clients--;
- }
-
- if (con_info->fp)
- fclose (con_info->fp);
+ MHD_destroy_post_processor (con_info->postprocessor);
+ nr_of_uploading_clients--;
}
+ if (con_info->fp)
+ fclose (con_info->fp);
+ }
+
free (con_info);
*con_cls = NULL;
}
-static int
+static enum MHD_Result
answer_to_connection (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -209,105 +219,109 @@
size_t *upload_data_size,
void **con_cls)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+
if (NULL == *con_cls)
- {
- /* First call, setup data structures */
- struct connection_info_struct *con_info;
+ {
+ /* First call, setup data structures */
+ struct connection_info_struct *con_info;
- if (nr_of_uploading_clients >= MAXCLIENTS)
- return send_page (connection,
- busypage,
- MHD_HTTP_SERVICE_UNAVAILABLE);
+ if (nr_of_uploading_clients >= MAXCLIENTS)
+ return send_page (connection,
+ busypage,
+ MHD_HTTP_SERVICE_UNAVAILABLE);
- con_info = malloc (sizeof (struct connection_info_struct));
- if (NULL == con_info)
- return MHD_NO;
- con_info->answercode = 0; /* none yet */
- con_info->fp = NULL;
+ con_info = malloc (sizeof (struct connection_info_struct));
+ if (NULL == con_info)
+ return MHD_NO;
+ con_info->answercode = 0; /* none yet */
+ con_info->fp = NULL;
- if (0 == strcasecmp (method, MHD_HTTP_METHOD_POST))
- {
- con_info->postprocessor =
- MHD_create_post_processor (connection,
- POSTBUFFERSIZE,
- &iterate_post,
- (void *) con_info);
-
- if (NULL == con_info->postprocessor)
- {
- free (con_info);
- return MHD_NO;
- }
-
- nr_of_uploading_clients++;
-
- con_info->connectiontype = POST;
- }
- else
- {
- con_info->connectiontype = GET;
- }
+ if (0 == strcasecmp (method, MHD_HTTP_METHOD_POST))
+ {
+ con_info->postprocessor =
+ MHD_create_post_processor (connection,
+ POSTBUFFERSIZE,
+ &iterate_post,
+ (void *) con_info);
+
+ if (NULL == con_info->postprocessor)
+ {
+ free (con_info);
+ return MHD_NO;
+ }
- *con_cls = (void *) con_info;
+ nr_of_uploading_clients++;
- return MHD_YES;
+ con_info->connectiontype = POST;
+ }
+ else
+ {
+ con_info->connectiontype = GET;
}
+ *con_cls = (void *) con_info;
+
+ return MHD_YES;
+ }
+
if (0 == strcasecmp (method, MHD_HTTP_METHOD_GET))
- {
- /* We just return the standard form for uploads on all GET requests */
- char buffer[1024];
+ {
+ /* We just return the standard form for uploads on all GET requests */
+ char buffer[1024];
- snprintf (buffer,
- sizeof (buffer),
- askpage,
- nr_of_uploading_clients);
- return send_page (connection,
- buffer,
- MHD_HTTP_OK);
- }
+ snprintf (buffer,
+ sizeof (buffer),
+ askpage,
+ nr_of_uploading_clients);
+ return send_page (connection,
+ buffer,
+ MHD_HTTP_OK);
+ }
if (0 == strcasecmp (method, MHD_HTTP_METHOD_POST))
+ {
+ struct connection_info_struct *con_info = *con_cls;
+
+ if (0 != *upload_data_size)
{
- struct connection_info_struct *con_info = *con_cls;
+ /* Upload not yet done */
+ if (0 != con_info->answercode)
+ {
+ /* we already know the answer, skip rest of upload */
+ *upload_data_size = 0;
+ return MHD_YES;
+ }
+ if (MHD_YES !=
+ MHD_post_process (con_info->postprocessor,
+ upload_data,
+ *upload_data_size))
+ {
+ con_info->answerstring = postprocerror;
+ con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
+ *upload_data_size = 0;
- if (0 != *upload_data_size)
- {
- /* Upload not yet done */
- if (0 != con_info->answercode)
- {
- /* we already know the answer, skip rest of upload */
- *upload_data_size = 0;
- return MHD_YES;
- }
- if (MHD_YES !=
- MHD_post_process (con_info->postprocessor,
- upload_data,
- *upload_data_size))
- {
- con_info->answerstring = postprocerror;
- con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
- }
- *upload_data_size = 0;
-
- return MHD_YES;
- }
- /* Upload finished */
- if (NULL != con_info->fp)
- {
- fclose (con_info->fp);
- con_info->fp = NULL;
- }
- if (0 == con_info->answercode)
- {
- /* No errors encountered, declare success */
- con_info->answerstring = completepage;
- con_info->answercode = MHD_HTTP_OK;
- }
- return send_page (connection,
- con_info->answerstring,
- con_info->answercode);
+ return MHD_YES;
+ }
+ /* Upload finished */
+ if (NULL != con_info->fp)
+ {
+ fclose (con_info->fp);
+ con_info->fp = NULL;
}
+ if (0 == con_info->answercode)
+ {
+ /* No errors encountered, declare success */
+ con_info->answerstring = completepage;
+ con_info->answercode = MHD_HTTP_OK;
+ }
+ return send_page (connection,
+ con_info->answerstring,
+ con_info->answercode);
+ }
/* Note a GET or a POST, generate error */
return send_page (connection,
@@ -324,14 +338,15 @@
daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD,
PORT, NULL, NULL,
&answer_to_connection, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &request_completed, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &request_completed,
+ NULL,
MHD_OPTION_END);
if (NULL == daemon)
- {
- fprintf (stderr,
- "Failed to start daemon\n");
- return 1;
- }
+ {
+ fprintf (stderr,
+ "Failed to start daemon.\n");
+ return 1;
+ }
(void) getchar ();
MHD_stop_daemon (daemon);
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/logging.c
^
|
@@ -14,21 +14,28 @@
#define PORT 8888
-static int
+static enum MHD_Result
print_out_key (void *cls, enum MHD_ValueKind kind, const char *key,
const char *value)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) kind; /* Unused. Silent compiler warning. */
printf ("%s: %s\n", key, value);
return MHD_YES;
}
-static int
+static enum MHD_Result
answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
size_t *upload_data_size, void **con_cls)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) con_cls; /* Unused. Silent compiler warning. */
printf ("New %s request for %s using version %s\n", method, url, version);
MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key,
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/sessions.c
^
|
@@ -11,7 +11,7 @@
#include <time.h>
#include <microhttpd.h>
-#if defined _WIN32 && !defined(__MINGW64_VERSION_MAJOR)
+#if defined _WIN32 && ! defined(__MINGW64_VERSION_MAJOR)
static int
asprintf (char **resultp, const char *format, ...)
{
@@ -32,7 +32,7 @@
if (result != NULL)
{
int len2 = _vscprintf ((char *) format, argptr);
- if (len2 != len - 1 || len2 <= 0)
+ if ((len2 != len - 1) || (len2 <= 0))
{
free (result);
result = NULL;
@@ -49,37 +49,45 @@
va_end (argptr);
return len;
}
+
+
#endif
/**
* Invalid method page.
*/
-#define METHOD_ERROR "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
+#define METHOD_ERROR \
+ "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
/**
* Invalid URL page.
*/
-#define NOT_FOUND_ERROR "<html><head><title>Not found</title></head><body>Go away.</body></html>"
+#define NOT_FOUND_ERROR \
+ "<html><head><title>Not found</title></head><body>Go away.</body></html>"
/**
* Front page. (/)
*/
-#define MAIN_PAGE "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
+#define MAIN_PAGE \
+ "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
/**
* Second page. (/2)
*/
-#define SECOND_PAGE "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
+#define SECOND_PAGE \
+ "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
/**
* Second page (/S)
*/
-#define SUBMIT_PAGE "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>"
+#define SUBMIT_PAGE \
+ "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>"
/**
* Last page.
*/
-#define LAST_PAGE "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
+#define LAST_PAGE \
+ "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
/**
* Name of our cookie.
@@ -159,8 +167,6 @@
static struct Session *sessions;
-
-
/**
* Return the session handle for this connection, or
* create one if this is a new user.
@@ -172,40 +178,40 @@
const char *cookie;
cookie = MHD_lookup_connection_value (connection,
- MHD_COOKIE_KIND,
- COOKIE_NAME);
+ MHD_COOKIE_KIND,
+ COOKIE_NAME);
if (cookie != NULL)
+ {
+ /* find existing session */
+ ret = sessions;
+ while (NULL != ret)
{
- /* find existing session */
- ret = sessions;
- while (NULL != ret)
- {
- if (0 == strcmp (cookie, ret->sid))
- break;
- ret = ret->next;
- }
- if (NULL != ret)
- {
- ret->rc++;
- return ret;
- }
+ if (0 == strcmp (cookie, ret->sid))
+ break;
+ ret = ret->next;
}
+ if (NULL != ret)
+ {
+ ret->rc++;
+ return ret;
+ }
+ }
/* create fresh session */
ret = calloc (1, sizeof (struct Session));
if (NULL == ret)
- {
- fprintf (stderr, "calloc error: %s\n", strerror (errno));
- return NULL;
- }
+ {
+ fprintf (stderr, "calloc error: %s\n", strerror (errno));
+ return NULL;
+ }
/* not a super-secure way to generate a random session ID,
but should do for a simple example... */
snprintf (ret->sid,
- sizeof (ret->sid),
- "%X%X%X%X",
- (unsigned int) rand (),
- (unsigned int) rand (),
- (unsigned int) rand (),
- (unsigned int) rand ());
+ sizeof (ret->sid),
+ "%X%X%X%X",
+ (unsigned int) rand (),
+ (unsigned int) rand (),
+ (unsigned int) rand (),
+ (unsigned int) rand ());
ret->rc++;
ret->start = time (NULL);
ret->next = sessions;
@@ -221,12 +227,12 @@
* @param mime mime type to use
* @param session session information
* @param connection connection to process
- * @param MHD_YES on success, MHD_NO on failure
+ * @param #MHD_YES on success, #MHD_NO on failure
*/
-typedef int (*PageHandler)(const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection);
+typedef enum MHD_Result (*PageHandler)(const void *cls,
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection);
/**
@@ -264,22 +270,22 @@
*/
static void
add_session_cookie (struct Session *session,
- struct MHD_Response *response)
+ struct MHD_Response *response)
{
char cstr[256];
snprintf (cstr,
- sizeof (cstr),
- "%s=%s",
- COOKIE_NAME,
- session->sid);
+ sizeof (cstr),
+ "%s=%s",
+ COOKIE_NAME,
+ session->sid);
if (MHD_NO ==
MHD_add_response_header (response,
- MHD_HTTP_HEADER_SET_COOKIE,
- cstr))
- {
- fprintf (stderr,
- "Failed to set session cookie header!\n");
- }
+ MHD_HTTP_HEADER_SET_COOKIE,
+ cstr))
+ {
+ fprintf (stderr,
+ "Failed to set session cookie header!\n");
+ }
}
@@ -292,27 +298,27 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
serve_simple_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
const char *form = cls;
struct MHD_Response *response;
/* return static form */
response = MHD_create_response_from_buffer (strlen (form),
- (void *) form,
- MHD_RESPMEM_PERSISTENT);
+ (void *) form,
+ MHD_RESPMEM_PERSISTENT);
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -326,35 +332,35 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
fill_v1_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
const char *form = cls;
char *reply;
struct MHD_Response *response;
if (-1 == asprintf (&reply,
- form,
- session->value_1))
- {
- /* oops */
- return MHD_NO;
- }
+ form,
+ session->value_1))
+ {
+ /* oops */
+ return MHD_NO;
+ }
/* return static form */
response = MHD_create_response_from_buffer (strlen (reply),
- (void *) reply,
- MHD_RESPMEM_MUST_FREE);
+ (void *) reply,
+ MHD_RESPMEM_MUST_FREE);
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -368,36 +374,36 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
fill_v1_v2_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
const char *form = cls;
char *reply;
struct MHD_Response *response;
if (-1 == asprintf (&reply,
- form,
- session->value_1,
- session->value_2))
- {
- /* oops */
- return MHD_NO;
- }
+ form,
+ session->value_1,
+ session->value_2))
+ {
+ /* oops */
+ return MHD_NO;
+ }
/* return static form */
response = MHD_create_response_from_buffer (strlen (reply),
- (void *) reply,
- MHD_RESPMEM_MUST_FREE);
+ (void *) reply,
+ MHD_RESPMEM_MUST_FREE);
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -411,25 +417,27 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
not_found_page (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) session; /* Unused. Silent compiler warning. */
/* unsupported HTTP method */
response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR),
- (void *) NOT_FOUND_ERROR,
- MHD_RESPMEM_PERSISTENT);
+ (void *) NOT_FOUND_ERROR,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_FOUND,
- response);
+ MHD_HTTP_NOT_FOUND,
+ response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
MHD_destroy_response (response);
return ret;
}
@@ -438,15 +446,13 @@
/**
* List of all pages served by this HTTP server.
*/
-static struct Page pages[] =
- {
- { "/", "text/html", &fill_v1_form, MAIN_PAGE },
- { "/2", "text/html", &fill_v1_v2_form, SECOND_PAGE },
- { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
- { "/F", "text/html", &serve_simple_form, LAST_PAGE },
- { NULL, NULL, ¬_found_page, NULL } /* 404 */
- };
-
+static struct Page pages[] = {
+ { "/", "text/html", &fill_v1_form, MAIN_PAGE },
+ { "/2", "text/html", &fill_v1_v2_form, SECOND_PAGE },
+ { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
+ { "/F", "text/html", &serve_simple_form, LAST_PAGE },
+ { NULL, NULL, ¬_found_page, NULL } /* 404 */
+};
/**
@@ -468,49 +474,53 @@
* @return MHD_YES to continue iterating,
* MHD_NO to abort the iteration
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *filename,
- const char *content_type,
- const char *transfer_encoding,
- const char *data, uint64_t off, size_t size)
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data, uint64_t off, size_t size)
{
struct Request *request = cls;
struct Session *session = request->session;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) filename; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
if (0 == strcmp ("DONE", key))
- {
- fprintf (stdout,
- "Session `%s' submitted `%s', `%s'\n",
- session->sid,
- session->value_1,
- session->value_2);
- return MHD_YES;
- }
+ {
+ fprintf (stdout,
+ "Session `%s' submitted `%s', `%s'\n",
+ session->sid,
+ session->value_1,
+ session->value_2);
+ return MHD_YES;
+ }
if (0 == strcmp ("v1", key))
- {
- if (size + off > sizeof(session->value_1))
- size = sizeof (session->value_1) - off;
- memcpy (&session->value_1[off],
- data,
- size);
- if (size + off < sizeof (session->value_1))
- session->value_1[size+off] = '\0';
- return MHD_YES;
- }
+ {
+ if (size + off > sizeof(session->value_1))
+ size = sizeof (session->value_1) - off;
+ memcpy (&session->value_1[off],
+ data,
+ size);
+ if (size + off < sizeof (session->value_1))
+ session->value_1[size + off] = '\0';
+ return MHD_YES;
+ }
if (0 == strcmp ("v2", key))
- {
- if (size + off > sizeof(session->value_2))
- size = sizeof (session->value_2) - off;
- memcpy (&session->value_2[off],
- data,
- size);
- if (size + off < sizeof (session->value_2))
- session->value_2[size+off] = '\0';
- return MHD_YES;
- }
+ {
+ if (size + off > sizeof(session->value_2))
+ size = sizeof (session->value_2) - off;
+ memcpy (&session->value_2[off],
+ data,
+ size);
+ if (size + off < sizeof (session->value_2))
+ session->value_2[size + off] = '\0';
+ return MHD_YES;
+ }
fprintf (stderr, "Unsupported form value `%s'\n", key);
return MHD_YES;
}
@@ -547,102 +557,104 @@
* can be set with the MHD_OPTION_NOTIFY_COMPLETED).
* Initially, <tt>*con_cls</tt> will be NULL.
* @return MHS_YES if the connection was handled successfully,
- * MHS_NO if the socket must be closed due to a serios
+ * MHS_NO if the socket must be closed due to a serious
* error while handling the request
*/
-static int
+static enum MHD_Result
create_response (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **ptr)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
{
struct MHD_Response *response;
struct Request *request;
struct Session *session;
- int ret;
+ enum MHD_Result ret;
unsigned int i;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
request = *ptr;
if (NULL == request)
+ {
+ request = calloc (1, sizeof (struct Request));
+ if (NULL == request)
{
- request = calloc (1, sizeof (struct Request));
- if (NULL == request)
- {
- fprintf (stderr, "calloc error: %s\n", strerror (errno));
- return MHD_NO;
- }
- *ptr = request;
- if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
- {
- request->pp = MHD_create_post_processor (connection, 1024,
- &post_iterator, request);
- if (NULL == request->pp)
- {
- fprintf (stderr, "Failed to setup post processor for `%s'\n",
- url);
- return MHD_NO; /* internal error */
- }
- }
- return MHD_YES;
+ fprintf (stderr, "calloc error: %s\n", strerror (errno));
+ return MHD_NO;
+ }
+ *ptr = request;
+ if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+ {
+ request->pp = MHD_create_post_processor (connection, 1024,
+ &post_iterator, request);
+ if (NULL == request->pp)
+ {
+ fprintf (stderr, "Failed to setup post processor for `%s'\n",
+ url);
+ return MHD_NO; /* internal error */
+ }
}
+ return MHD_YES;
+ }
if (NULL == request->session)
+ {
+ request->session = get_session (connection);
+ if (NULL == request->session)
{
- request->session = get_session (connection);
- if (NULL == request->session)
- {
- fprintf (stderr, "Failed to setup session for `%s'\n",
- url);
- return MHD_NO; /* internal error */
- }
+ fprintf (stderr, "Failed to setup session for `%s'\n",
+ url);
+ return MHD_NO; /* internal error */
}
+ }
session = request->session;
session->start = time (NULL);
if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+ {
+ /* evaluate POST data */
+ MHD_post_process (request->pp,
+ upload_data,
+ *upload_data_size);
+ if (0 != *upload_data_size)
{
- /* evaluate POST data */
- MHD_post_process (request->pp,
- upload_data,
- *upload_data_size);
- if (0 != *upload_data_size)
- {
- *upload_data_size = 0;
- return MHD_YES;
- }
- /* done with POST data, serve response */
- MHD_destroy_post_processor (request->pp);
- request->pp = NULL;
- method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
- if (NULL != request->post_url)
- url = request->post_url;
+ *upload_data_size = 0;
+ return MHD_YES;
}
+ /* done with POST data, serve response */
+ MHD_destroy_post_processor (request->pp);
+ request->pp = NULL;
+ method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
+ if (NULL != request->post_url)
+ url = request->post_url;
+ }
if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
(0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
- {
- /* find out which page to serve */
- i=0;
- while ( (pages[i].url != NULL) &&
- (0 != strcmp (pages[i].url, url)) )
- i++;
- ret = pages[i].handler (pages[i].handler_cls,
- pages[i].mime,
- session, connection);
- if (ret != MHD_YES)
- fprintf (stderr, "Failed to create page for `%s'\n",
- url);
- return ret;
- }
+ {
+ /* find out which page to serve */
+ i = 0;
+ while ( (pages[i].url != NULL) &&
+ (0 != strcmp (pages[i].url, url)) )
+ i++;
+ ret = pages[i].handler (pages[i].handler_cls,
+ pages[i].mime,
+ session, connection);
+ if (ret != MHD_YES)
+ fprintf (stderr, "Failed to create page for `%s'\n",
+ url);
+ return ret;
+ }
/* unsupported HTTP method */
response = MHD_create_response_from_buffer (strlen (METHOD_ERROR),
- (void *) METHOD_ERROR,
- MHD_RESPMEM_PERSISTENT);
+ (void *) METHOD_ERROR,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_ACCEPTABLE,
- response);
+ MHD_HTTP_NOT_ACCEPTABLE,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -659,11 +671,14 @@
*/
static void
request_completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct Request *request = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == request)
return;
@@ -691,21 +706,21 @@
prev = NULL;
pos = sessions;
while (NULL != pos)
+ {
+ next = pos->next;
+ if (now - pos->start > 60 * 60)
{
- next = pos->next;
- if (now - pos->start > 60 * 60)
- {
- /* expire sessions after 1h */
- if (NULL == prev)
- sessions = pos->next;
- else
- prev->next = next;
- free (pos);
- }
+ /* expire sessions after 1h */
+ if (NULL == prev)
+ sessions = pos->next;
else
- prev = pos;
- pos = next;
+ prev->next = next;
+ free (pos);
}
+ else
+ prev = pos;
+ pos = next;
+ }
}
@@ -726,48 +741,49 @@
MHD_UNSIGNED_LONG_LONG mhd_timeout;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
/* initialize PRNG */
srand ((unsigned int) time (NULL));
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL,
- &create_response, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
- MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL,
- MHD_OPTION_END);
+ &create_response, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ &request_completed_callback, NULL,
+ MHD_OPTION_END);
if (NULL == d)
return 1;
while (1)
- {
- expire_sessions ();
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- break; /* fatal internal error */
- if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
- {
- tv.tv_sec = mhd_timeout / 1000;
- tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
- tvp = &tv;
- }
- else
- tvp = NULL;
- if (-1 == select (max + 1, &rs, &ws, &es, tvp))
- {
- if (EINTR != errno)
- fprintf (stderr,
- "Aborting due to error during select: %s\n",
- strerror (errno));
- break;
- }
- MHD_run (d);
+ {
+ expire_sessions ();
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ break; /* fatal internal error */
+ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
+ {
+ tv.tv_sec = mhd_timeout / 1000;
+ tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
+ tvp = &tv;
+ }
+ else
+ tvp = NULL;
+ if (-1 == select (max + 1, &rs, &ws, &es, tvp))
+ {
+ if (EINTR != errno)
+ fprintf (stderr,
+ "Aborting due to error during select: %s\n",
+ strerror (errno));
+ break;
}
+ MHD_run (d);
+ }
MHD_stop_daemon (d);
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/simplepost.c
^
|
@@ -13,7 +13,7 @@
#include <string.h>
#include <stdlib.h>
-#if defined(_MSC_VER) && _MSC_VER+0 <= 1800
+#if defined(_MSC_VER) && _MSC_VER + 0 <= 1800
/* Substitution is OK while return value is not used */
#define snprintf _snprintf
#endif
@@ -33,7 +33,8 @@
struct MHD_PostProcessor *postprocessor;
};
-const char *askpage = "<html><body>\
+const char *askpage =
+ "<html><body>\
What's your name, Sir?<br>\
<form action=\"/namepost\" method=\"post\">\
<input name=\"name\" type=\"text\">\
@@ -47,17 +48,17 @@
"<html><body>This doesn't seem to be right.</body></html>";
-static int
+static enum MHD_Result
send_page (struct MHD_Connection *connection, const char *page)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
response =
MHD_create_response_from_buffer (strlen (page), (void *) page,
- MHD_RESPMEM_PERSISTENT);
- if (!response)
+ MHD_RESPMEM_PERSISTENT);
+ if (! response)
return MHD_NO;
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
@@ -67,123 +68,138 @@
}
-static int
+static enum MHD_Result
iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
const char *filename, const char *content_type,
const char *transfer_encoding, const char *data, uint64_t off,
size_t size)
{
struct connection_info_struct *con_info = coninfo_cls;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) filename; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
+ (void) off; /* Unused. Silent compiler warning. */
if (0 == strcmp (key, "name"))
+ {
+ if ((size > 0) && (size <= MAXNAMESIZE))
{
- if ((size > 0) && (size <= MAXNAMESIZE))
- {
- char *answerstring;
- answerstring = malloc (MAXANSWERSIZE);
- if (!answerstring)
- return MHD_NO;
-
- snprintf (answerstring, MAXANSWERSIZE, greetingpage, data);
- con_info->answerstring = answerstring;
- }
- else
- con_info->answerstring = NULL;
+ char *answerstring;
+ answerstring = malloc (MAXANSWERSIZE);
+ if (! answerstring)
+ return MHD_NO;
- return MHD_NO;
+ snprintf (answerstring, MAXANSWERSIZE, greetingpage, data);
+ con_info->answerstring = answerstring;
}
+ else
+ con_info->answerstring = NULL;
+
+ return MHD_NO;
+ }
return MHD_YES;
}
+
static void
request_completed (void *cls, struct MHD_Connection *connection,
void **con_cls, enum MHD_RequestTerminationCode toe)
{
struct connection_info_struct *con_info = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == con_info)
return;
if (con_info->connectiontype == POST)
- {
- MHD_destroy_post_processor (con_info->postprocessor);
- if (con_info->answerstring)
- free (con_info->answerstring);
- }
+ {
+ MHD_destroy_post_processor (con_info->postprocessor);
+ if (con_info->answerstring)
+ free (con_info->answerstring);
+ }
free (con_info);
*con_cls = NULL;
}
-static int
+static enum MHD_Result
answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
size_t *upload_data_size, void **con_cls)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+
if (NULL == *con_cls)
- {
- struct connection_info_struct *con_info;
+ {
+ struct connection_info_struct *con_info;
+
+ con_info = malloc (sizeof (struct connection_info_struct));
+ if (NULL == con_info)
+ return MHD_NO;
+ con_info->answerstring = NULL;
- con_info = malloc (sizeof (struct connection_info_struct));
- if (NULL == con_info)
+ if (0 == strcmp (method, "POST"))
+ {
+ con_info->postprocessor =
+ MHD_create_post_processor (connection, POSTBUFFERSIZE,
+ iterate_post, (void *) con_info);
+
+ if (NULL == con_info->postprocessor)
+ {
+ free (con_info);
return MHD_NO;
- con_info->answerstring = NULL;
+ }
- if (0 == strcmp (method, "POST"))
- {
- con_info->postprocessor =
- MHD_create_post_processor (connection, POSTBUFFERSIZE,
- iterate_post, (void *) con_info);
-
- if (NULL == con_info->postprocessor)
- {
- free (con_info);
- return MHD_NO;
- }
-
- con_info->connectiontype = POST;
- }
- else
- con_info->connectiontype = GET;
+ con_info->connectiontype = POST;
+ }
+ else
+ con_info->connectiontype = GET;
- *con_cls = (void *) con_info;
+ *con_cls = (void *) con_info;
- return MHD_YES;
- }
+ return MHD_YES;
+ }
if (0 == strcmp (method, "GET"))
- {
- return send_page (connection, askpage);
- }
+ {
+ return send_page (connection, askpage);
+ }
if (0 == strcmp (method, "POST"))
+ {
+ struct connection_info_struct *con_info = *con_cls;
+
+ if (*upload_data_size != 0)
{
- struct connection_info_struct *con_info = *con_cls;
+ MHD_post_process (con_info->postprocessor, upload_data,
+ *upload_data_size);
+ *upload_data_size = 0;
- if (*upload_data_size != 0)
- {
- MHD_post_process (con_info->postprocessor, upload_data,
- *upload_data_size);
- *upload_data_size = 0;
-
- return MHD_YES;
- }
- else if (NULL != con_info->answerstring)
- return send_page (connection, con_info->answerstring);
+ return MHD_YES;
}
+ else if (NULL != con_info->answerstring)
+ return send_page (connection, con_info->answerstring);
+ }
return send_page (connection, errorpage);
}
+
int
main ()
{
struct MHD_Daemon *daemon;
- daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, PORT, NULL, NULL,
+ daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ PORT, NULL, NULL,
&answer_to_connection, NULL,
MHD_OPTION_NOTIFY_COMPLETED, request_completed,
NULL, MHD_OPTION_END);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/examples/tlsauthentication.c
^
|
@@ -29,34 +29,32 @@
const char *lookup =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned long l;
- int i;
+ size_t i;
char *tmp;
size_t length = strlen (message);
- tmp = malloc (length * 2);
+ tmp = malloc (length * 2 + 1);
if (NULL == tmp)
- return tmp;
-
+ return NULL;
tmp[0] = 0;
-
for (i = 0; i < length; i += 3)
- {
- l = (((unsigned long) message[i]) << 16)
+ {
+ l = (((unsigned long) message[i]) << 16)
| (((i + 1) < length) ? (((unsigned long) message[i + 1]) << 8) : 0)
| (((i + 2) < length) ? ((unsigned long) message[i + 2]) : 0);
- strncat (tmp, &lookup[(l >> 18) & 0x3F], 1);
- strncat (tmp, &lookup[(l >> 12) & 0x3F], 1);
+ strncat (tmp, &lookup[(l >> 18) & 0x3F], 1);
+ strncat (tmp, &lookup[(l >> 12) & 0x3F], 1);
- if (i + 1 < length)
- strncat (tmp, &lookup[(l >> 6) & 0x3F], 1);
- if (i + 2 < length)
- strncat (tmp, &lookup[l & 0x3F], 1);
- }
+ if (i + 1 < length)
+ strncat (tmp, &lookup[(l >> 6) & 0x3F], 1);
+ if (i + 2 < length)
+ strncat (tmp, &lookup[l & 0x3F], 1);
+ }
if (length % 3)
- strncat (tmp, "===", 3 - length % 3);
+ strncat (tmp, "==", 3 - length % 3);
return tmp;
}
@@ -69,16 +67,16 @@
fp = fopen (filename, "rb");
if (fp)
- {
- long size;
+ {
+ long size;
- if ((0 != fseek (fp, 0, SEEK_END)) || (-1 == (size = ftell (fp))))
- size = 0;
+ if ((0 != fseek (fp, 0, SEEK_END)) || (-1 == (size = ftell (fp))))
+ size = 0;
- fclose (fp);
+ fclose (fp);
- return size;
- }
+ return size;
+ }
else
return 0;
}
@@ -101,66 +99,74 @@
buffer = malloc (size + 1);
if (! buffer)
- {
- fclose (fp);
- return NULL;
- }
+ {
+ fclose (fp);
+ return NULL;
+ }
buffer[size] = '\0';
- if (size != fread (buffer, 1, size, fp))
- {
- free (buffer);
- buffer = NULL;
- }
+ if (size != (long) fread (buffer, 1, size, fp))
+ {
+ free (buffer);
+ buffer = NULL;
+ }
fclose (fp);
return buffer;
}
-static int
+static enum MHD_Result
ask_for_authentication (struct MHD_Connection *connection, const char *realm)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
char *headervalue;
+ size_t slen;
const char *strbase = "Basic realm=";
response = MHD_create_response_from_buffer (0, NULL,
- MHD_RESPMEM_PERSISTENT);
- if (!response)
+ MHD_RESPMEM_PERSISTENT);
+ if (! response)
return MHD_NO;
- headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
- if (!headervalue)
+ slen = strlen (strbase) + strlen (realm) + 1;
+ if (NULL == (headervalue = malloc (slen)))
return MHD_NO;
-
- strcpy (headervalue, strbase);
- strcat (headervalue, realm);
-
- ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
+ snprintf (headervalue,
+ slen,
+ "%s%s",
+ strbase,
+ realm);
+ ret = MHD_add_response_header (response,
+ "WWW-Authenticate",
+ headervalue);
free (headervalue);
- if (!ret)
- {
- MHD_destroy_response (response);
- return MHD_NO;
- }
-
- ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
+ if (! ret)
+ {
+ MHD_destroy_response (response);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ response);
MHD_destroy_response (response);
-
return ret;
}
+
static int
is_authenticated (struct MHD_Connection *connection,
- const char *username, const char *password)
+ const char *username,
+ const char *password)
{
const char *headervalue;
- char *expected_b64, *expected;
+ char *expected_b64;
+ char *expected;
const char *strbase = "Basic ";
int authenticated;
+ size_t slen;
headervalue =
MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
@@ -170,14 +176,14 @@
if (0 != strncmp (headervalue, strbase, strlen (strbase)))
return 0;
- expected = malloc (strlen (username) + 1 + strlen (password) + 1);
- if (NULL == expected)
+ slen = strlen (username) + 1 + strlen (password) + 1;
+ if (NULL == (expected = malloc (slen)))
return 0;
-
- strcpy (expected, username);
- strcat (expected, ":");
- strcat (expected, password);
-
+ snprintf (expected,
+ slen,
+ "%s:%s",
+ username,
+ password);
expected_b64 = string_to_base64 (expected);
free (expected);
if (NULL == expected_b64)
@@ -185,24 +191,22 @@
authenticated =
(strcmp (headervalue + strlen (strbase), expected_b64) == 0);
-
free (expected_b64);
-
return authenticated;
}
-static int
+static enum MHD_Result
secret_page (struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
const char *page = "<html><body>A secret.</body></html>";
response =
MHD_create_response_from_buffer (strlen (page), (void *) page,
- MHD_RESPMEM_PERSISTENT);
- if (!response)
+ MHD_RESPMEM_PERSISTENT);
+ if (! response)
return MHD_NO;
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
@@ -212,21 +216,27 @@
}
-static int
+static enum MHD_Result
answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
size_t *upload_data_size, void **con_cls)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
if (0 != strcmp (method, "GET"))
return MHD_NO;
if (NULL == *con_cls)
- {
- *con_cls = connection;
- return MHD_YES;
- }
+ {
+ *con_cls = connection;
+ return MHD_YES;
+ }
- if (!is_authenticated (connection, USER, PASSWORD))
+ if (! is_authenticated (connection, USER, PASSWORD))
return ask_for_authentication (connection, REALM);
return secret_page (connection);
@@ -244,14 +254,14 @@
cert_pem = load_file (SERVERCERTFILE);
if ((key_pem == NULL) || (cert_pem == NULL))
- {
- printf ("The key/certificate files could not be read.\n");
- if (NULL != key_pem)
- free (key_pem);
- if (NULL != cert_pem)
- free (cert_pem);
- return 1;
- }
+ {
+ printf ("The key/certificate files could not be read.\n");
+ if (NULL != key_pem)
+ free (key_pem);
+ if (NULL != cert_pem)
+ free (cert_pem);
+ return 1;
+ }
daemon =
MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS, PORT, NULL,
@@ -259,14 +269,14 @@
MHD_OPTION_HTTPS_MEM_KEY, key_pem,
MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END);
if (NULL == daemon)
- {
- printf ("%s\n", cert_pem);
+ {
+ printf ("%s\n", cert_pem);
- free (key_pem);
- free (cert_pem);
+ free (key_pem);
+ free (cert_pem);
- return 1;
- }
+ return 1;
+ }
(void) getchar ();
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/gpl-2.0.texi
^
|
@@ -0,0 +1,389 @@
+@c The GNU General Public License.
+@center Version 2, June 1991
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@heading Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+@enumerate 0
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and ``any
+later version'', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+
+@end ifinfo
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+
+@end ifinfo
+
+@page
+@heading Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and a brief idea of what it does.}
+Copyright (C) @var{yyyy} @var{name of author}
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) @var{year} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@example
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end example
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/libmicrohttpd-tutorial.texi
^
|
@@ -24,7 +24,7 @@
Copyright (c) 2008 Sebastian Gerhardt.
-Copyright (c) 2010, 2011, 2012, 2013, 2016 Christian Grothoff.
+Copyright (c) 2010, 2011, 2012, 2013, 2016, 2021 Christian Grothoff.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/libmicrohttpd.3
^
|
@@ -1,35 +1,45 @@
-.TH LIBMICROHTTPD "3" "21 Jun 2013 "libmicrohttpd"
-.SH "NAME"
-GNU libmicrohttpd \- library for embedding HTTP servers
-.SH "SYNOPSIS"
-
- \fB#include <microhttpd.h>
-
-.SH "DESCRIPTION"
-.P
+.Dd June 21, 2013
+.Dt LIBMICROHTTPD 3
+.Os
+.Sh NAME
+.Nm libmicrohttpd
+.Nd library for embedding HTTP servers
+.Sh LIBRARY
+.Lb libmicrohttpd
+.Sh SYNOPSIS
+.In microhttpd.h
+.Sh DESCRIPTION
GNU libmicrohttpd (short MHD) allows applications to easily integrate the functionality of a simple HTTP server. MHD is a GNU package.
-.P
-The details of the API are described in comments in the header file, a detailed reference documentation, a tutorial, and in brief on the MHD webpage.
-.P
-.SH "SEE ALSO"
-\fBcurl\fP(1), \fBlibcurl\fP(3)
-
-.SH "LEGAL NOTICE"
-libmicrohttpd is released under both the LGPL Version 2.1 or higher and the GNU GPL with eCos extension. For details on both licenses please read the respective appendix in the manual.
-
-.SH "FILES"
-.TP
-microhttpd.h
+.sp
+The details of the API are described in comments in the header file, a detailed reference documentation in Texinfo, a tutorial, and in brief on the MHD webpage.
+.Sh LEGAL NOTICE
+libmicrohttpd is released under both the LGPL Version 2.1 or higher and the GNU GPL with eCos extension. For details on both licenses please read the respective appendix in the Texinfo manual.
+.Sh FILES
+.Bl -tag -width /etc/ttys -compact
+.It Pa microhttpd.h
libmicrohttpd include file
-.TP
-libmicrohttpd.so
+.It Pa libmicrohttpd.so
libmicrohttpd library
-
-.SH "REPORTING BUGS"
-Report bugs by using mantis <https://gnunet.org/bugs/>.
-
-.SH "AUTHORS"
-GNU libmicrohttpd was originally designed by Christian Grothoff <christian@grothoff.org> and Chris GauthierDickey <chrisg@cs.du.edu>. The original implementation was done by Daniel Pittman <depittman@gmail.com> and Christian Grothoff. SSL/TLS support was added by Sagie Amir using code from GnuTLS. See the AUTHORS file in the distribution for a more detailed list of contributors.
-
-.SH "AVAILABILITY"
-You can obtain the latest version from http://www.gnu.org/software/libmicrohttpd/.
+.El
+.Sh SEE ALSO
+.Xr curl 1 ,
+.Xr libcurl 3 ,
+info libmicrohttpd
+.Sh AUTHORS
+GNU
+.Nm
+was originally designed by
+.An -nosplit
+.An Christian Grothoff Aq Mt christian@grothoff.org
+and
+.An Chris GauthierDickey Aq Mt chrisg@cs.du.edu Ns .
+The original implementation was done by
+.An Daniel Pittman Aq Mt depittman@gmail.com
+and Christian Grothoff.
+SSL/TLS support was added by Sagie Amir using code from GnuTLS. See the AUTHORS file in the distribution for a more detailed list of contributors.
+.Sh AVAILABILITY
+You can obtain the latest version from
+.Lk https://www.gnu.org/software/libmicrohttpd/ Ns .
+.Sh BUGS
+Report bugs by using
+.Lk https://gnunet.org/bugs/ "Mantis" Ns .
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/libmicrohttpd.texi
^
|
@@ -12,7 +12,7 @@
(version @value{VERSION}, @value{UPDATED}), a library for embedding
an HTTP(S) server into C applications.
-Copyright @copyright{} 2007--2017 Christian Grothoff
+Copyright @copyright{} 2007--2019 Christian Grothoff
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -72,8 +72,8 @@
* GNU-LGPL:: The GNU Lesser General Public License says how you
can copy and share almost all of `libmicrohttpd'.
-* GNU GPL with eCos Extension:: The GNU General Public License with eCos extension says how you
- can copy and share some parts of `libmicrohttpd'.
+* eCos License:: The eCos License says how you can copy and share some parts of `libmicrohttpd'.
+* GNU-GPL:: The GNU General Public License (with eCos extension) says how you can copy and share some parts of `libmicrohttpd'.
* GNU-FDL:: The GNU Free Documentation License says how you
can copy and share the documentation of `libmicrohttpd'.
@@ -192,7 +192,7 @@
@float Figure,fig:performance
-@image{performance_data,400pt,300pt,Data,.png}
+@image{libmicrohttpd_performance_data,400pt,300pt,Data,.png}
@caption{Performance measurements for select vs. epoll (with thread-pool).}
@end float
@@ -277,15 +277,27 @@
@item ``--enable-coverage''
set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries)
+@item ``--with-threads=posix,w32,none,auto''
+sets threading library to use. With use ``none'' to not support threads. In this case, MHD will only support the ``external'' threading modes and not perform any locking of data structures! Use @code{MHD_is_feature_supported(MHD_FEATURE_THREADS)} to test if threads are available. Default is ``auto''.
+
@item ``--with-gcrypt=PATH''
specifies path to libgcrypt installation
@item ``--with-gnutls=PATH''
specifies path to libgnutls installation
-
@end table
+To cross-compile MHD for Android, install the Android NDK and use:
+@verbatim
+./configure --target=arm-linux-androideabi --host=arm-linux-androideabi --disable-doc --disable-examples
+make
+@end verbatim
+
+Similar build commands should work for cross-compilation to other platforms.
+Note that you may have to first cross-compile GnuTLS to get MHD with TLS support.
+
+
@section Validity of pointers
MHD will give applications access to its internal data structures
@@ -448,8 +460,7 @@
Starting the daemon may also fail if a particular option is not
implemented or not supported on the target platform (i.e. no support
for @acronym{TLS}, threads or IPv6). TLS support generally depends on
-options given during MHD compilation. Threaded operations (including
-@code{MHD_USE_INTERNAL_POLLING_THREAD}) are not supported on Symbian.
+options given during MHD compilation.
@table @code
@item MHD_NO_FLAG
@@ -537,7 +548,7 @@
Enable optimizations to aggressively improve performance.
Currently, the optimizations this option enables are based on
-opportunistic reads and writes. Bascially, MHD will simply try to
+opportunistic reads and writes. Basically, MHD will simply try to
read or write or accept on a socket before checking that the socket is
ready for IO using the event loop mechanism. As the sockets are
non-blocking, this may fail (at a loss of performance), but generally
@@ -613,6 +624,26 @@
specific polling function, it's recommended to use this flag. This
flag is very convenient for multiplatform applications.
+@item MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT
+Tell the TLS library to support post handshake client authentication.
+Only useful in combination with @code{MHD_USE_TLS}.
+
+This option will only work if the underlying TLS library
+supports it (i.e. GnuTLS after 3.6.3). If the TLS library
+does not support it, MHD may ignore the option and proceed
+without supporting this features.
+
+@item MHD_USE_INSECURE_TLS_EARLY_DATA
+Tell the TLS library to support TLS v1.3 early data (0-RTT) with the
+resulting security drawbacks. Only enable this if you really know what
+you are doing. MHD currently does NOT enforce that this only affects
+GET requests! You have been warned.
+
+This option will only work if the underlying TLS library
+supports it (i.e. GnuTLS after 3.6.3). If the TLS library
+does not support it, MHD may ignore the option and proceed
+without supporting this features.
+
@end table
@end deftp
@@ -754,6 +785,15 @@
It is not recommended to set it to -1 on publicly available servers as
it may potentially lower level of protection.
+@item MHD_OPTION_SERVER_INSANITY
+@cindex testing
+Allows the application to disable certain sanity precautions in MHD. With
+these, the client can break the HTTP protocol, so this should never be used in
+production. The options are, however, useful for testing HTTP clients against
+"broken" server implementations. This argument must be followed by an
+@code{unsigned int}, corresponding to an @code{enum MHD_DisableSanityCheck}.
+
+Right now, no sanity checks can be disabled.
@item MHD_OPTION_SOCK_ADDR
@cindex bind, restricting bind
@@ -870,6 +910,29 @@
using gnutls_server_name_get(). Using this option requires GnuTLS 3.0
or higher.
+@item MHD_OPTION_HTTPS_CERT_CALLBACK2
+@cindex SSL
+@cindex TLS
+@cindex SNI
+@cindex OCSP
+Use a callback to determine which X.509 certificate should be
+used for a given HTTPS connection. This option should be
+followed by a argument of type `gnutls_certificate_retrieve_function3 *`.
+This option provides an
+alternative/extension to #MHD_OPTION_HTTPS_CERT_CALLBACK.
+You must use this version if you want to use OCSP stapling.
+Using this option requires GnuTLS 3.6.3 or higher.
+
+@item MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
+@cindex SSL
+@cindex TLS
+@cindex PSK
+Use pre-shared key for TLS credentials.
+Pass a pointer to callback of type
+@code{MHD_PskServerCredentialsCallback} and a closure.
+The function will be called to
+retrieve the shared key for a given username.
+
@item MHD_OPTION_DIGEST_AUTH_RANDOM
@cindex digest auth
@cindex random
@@ -929,10 +992,10 @@
@cindex performance
Number (unsigned int) of threads in thread pool. Enable
thread pooling by setting this value to to something
-greater than 1. Currently, thread model must be
+greater than 1. Currently, thread mode must be
MHD_USE_INTERNAL_POLLING_THREAD if thread pooling is enabled
(@code{MHD_start_daemon} returns @code{NULL} for an unsupported thread
-model).
+mode).
@item MHD_OPTION_ARRAY
@cindex options
@@ -1135,6 +1198,38 @@
do not (automatically) sent "Connection" headers and always
close the connection after generating the response.
+By default, MHD will respond using the same HTTP version which
+was set in the request. You can also set the
+@code{MHD_RF_HTTP_VERSION_1_0_RESPONSE} flag to force version 1.0
+in the response.
+
+@item MHD_RF_HTTP_VERSION_1_0_RESPONSE
+Only respond in HTTP 1.0-mode. Contrary to the
+@code{MHD_RF_HTTP_VERSION_1_0_ONLY} flag, the response's HTTP version will
+always be set to 1.0 and ``Connection'' headers are still supported.
+
+You can even combine this option with MHD_RF_HTTP_VERSION_1_0_ONLY to
+change the response's HTTP version while maintaining strict compliance
+with HTTP 1.0 regarding connection management.
+
+This solution is not perfect as this flag is set on the response which
+is created after header processing. So MHD will behave as a HTTP 1.1
+server until the response is queued. It means that an invalid HTTP 1.1
+request will fail even if the response is sent with HTTP 1.0 and the
+request would be valid if interpreted with this version. For example,
+this request will fail in strict mode:
+
+@verbatim
+GET / HTTP/1.1
+@end verbatim
+
+as the ``Host'' header is missing and is mandatory in HTTP 1.1, but it
+should succeed when interpreted with HTTP 1.0.
+
+@item MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
+Disable sanity check preventing clients from manually
+setting the HTTP content length option.
+
@end table
@end deftp
@@ -1175,6 +1270,11 @@
@end deftp
+@deftp {C Struct} MHD_IoVec
+An element of an array of memory buffers.
+@end deftp
+
+
@deftp {C Struct} MHD_PostProcessor
@cindex POST method
Handle for @code{POST} processing.
@@ -1198,7 +1298,7 @@
@chapter Callback functions definition
-@deftypefn {Function Pointer} int {*MHD_AcceptPolicyCallback} (void *cls, const struct sockaddr * addr, socklen_t addrlen)
+@deftypefn {Function Pointer} enum MHD_Result {*MHD_AcceptPolicyCallback} (void *cls, const struct sockaddr * addr, socklen_t addrlen)
Invoked in the context of a connection to allow or deny a client to
connect. This callback return @code{MHD_YES} if connection is allowed,
@code{MHD_NO} if not.
@@ -1214,7 +1314,7 @@
@end deftypefn
-@deftypefn {Function Pointer} int {*MHD_AccessHandlerCallback} (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
+@deftypefn {Function Pointer} enum MHD_Result {*MHD_AccessHandlerCallback} (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
Invoked in the context of a connection to answer a request from the
client. This callback must call MHD functions (example: the
@code{MHD_Response} ones) to provide content to give back to the client
@@ -1317,7 +1417,7 @@
@end deftypefn
-@deftypefn {Function Pointer} int {*MHD_KeyValueIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
+@deftypefn {Function Pointer} enum MHD_Result {*MHD_KeyValueIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *value, size_t value_size)
Iterator over key-value pairs. This iterator can be used to iterate
over all of the cookies, headers, or @code{POST}-data fields of a
request, and also to iterate over the headers that have been added to a
@@ -1336,6 +1436,17 @@
@item value
value corresponding value, can be NULL
+@item value_size
+number of bytes in @code{value}. This argument was introduced in
+@code{MHD_VERSION} 0x00096301 to allow applications to use binary
+zeros in values. Applications using this argument must ensure that
+they are using a sufficiently recent version of MHD, i.e. by testing
+@code{MHD_get_version()} for values above or equal to 0.9.64.
+Applications that do not need zeros in values and that want to compile
+without warnings against newer versions of MHD should not declare this
+argument and cast the function pointer argument to
+@code{MHD_KeyValueIterator}.
+
@end table
Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the
@@ -1343,7 +1454,7 @@
@end deftypefn
-@deftypefn {Function Pointer} int {*MHD_ContentReaderCallback} (void *cls, uint64_t pos, char *buf, size_t max)
+@deftypefn {Function Pointer} ssize_t {*MHD_ContentReaderCallback} (void *cls, uint64_t pos, char *buf, size_t max)
Callback used by MHD in order to obtain content. The callback has to
copy at most @var{max} bytes of content into @var{buf}. The total
number of bytes that has been placed into @var{buf} should be returned.
@@ -1399,7 +1510,7 @@
@end deftypefn
-@deftypefn {Function Pointer} int {*MHD_PostDataIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
+@deftypefn {Function Pointer} enum MHD_Result {*MHD_PostDataIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
Iterator over key-value pairs where the value maybe made available in
increments and/or may not be zero-terminated. Used for processing
@code{POST} data.
@@ -1490,7 +1601,7 @@
@end deftypefun
-@deftypefun int MHD_quiesce_daemon (struct MHD_Daemon *daemon)
+@deftypefun MHD_socket MHD_quiesce_daemon (struct MHD_Daemon *daemon)
@cindex quiesce
Stop accepting connections from the listening socket. Allows clients
to continue processing, but stops accepting new connections. Note
@@ -1516,7 +1627,7 @@
@end deftypefun
-@deftypefun int MHD_run (struct MHD_Daemon *daemon)
+@deftypefun enum MHD_Result MHD_run (struct MHD_Daemon *daemon)
Run webserver operations (without blocking unless in client callbacks).
This method should be called by clients in combination with
@code{MHD_get_fdset()} if the client-controlled @code{select}-method is used.
@@ -1537,7 +1648,7 @@
@end deftypefun
-@deftypefun int MHD_run_from_select (struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
+@deftypefun enum MHD_Result MHD_run_from_select (struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Run webserver operations given sets of ready socket handles.
@cindex select
@@ -1613,7 +1724,7 @@
@chapter Implementing external @code{select}
-@deftypefun int MHD_get_fdset (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
+@deftypefun enum MHD_Result MHD_get_fdset (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
Obtain the @code{select()} sets for this daemon. The daemon's socket
is added to @var{read_fd_set}. The list of currently existent
connections is scanned and their file descriptors added to the correct
@@ -1639,12 +1750,12 @@
@end deftypefun
-@deftypefun int MHD_get_fdset2 (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd, unsigned int fd_setsize)
+@deftypefun enum MHD_Result MHD_get_fdset2 (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd, unsigned int fd_setsize)
Like @code{MHD_get_fdset()}, except that you can manually specify the value of FD_SETSIZE used by your application.
@end deftypefun
-@deftypefun int MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout)
+@deftypefun enum MHD_Result MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout)
@cindex timeout
Obtain timeout value for select for this daemon (only needed if
connection timeout is used). The returned value is how many
@@ -1664,7 +1775,7 @@
@end table
Return @code{MHD_YES} on success, @code{MHD_NO} if timeouts are not used
-(or no connections exist that would necessiate the use of a timeout
+(or no connections exist that would necessitate the use of a timeout
right now).
@end deftypefun
@@ -1705,7 +1816,7 @@
@end deftypefun
-@deftypefun int MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
+@deftypefun enum MHD_Result MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
This function can be used to append an entry to
the list of HTTP headers of a connection (so that the
@code{MHD_get_connection_values function} will return
@@ -1740,12 +1851,18 @@
@var{kind}, return one of them (the ``first'', whatever that means).
@var{key} must reference a zero-terminated ASCII-coded string
representing the header to look for: it is compared against the
-headers using @code{strcasecmp()}, so case is ignored. A value of
-@code{NULL} for @var{key} can be used to lookup 'trailing' values without a
-key, for example if a URI is of the form
-``http://example.com/?trailer'', a @var{key} of @code{NULL} can be used to
-access ``tailer" The function returns @code{NULL} if no matching item
-was found.
+headers using (basically) @code{strcasecmp()}, so case is ignored.
+@end deftypefun
+
+@deftypefun {const char *} MHD_lookup_connection_value_n (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char **value_ptr, size_t *value_size_ptr)
+Get a particular header value. If multiple values match the
+@var{kind}, return one of them (the ``first'', whatever that means).
+@var{key} must reference an ASCII-coded string
+representing the header to look for: it is compared against the
+headers using (basically) @code{strncasecmp()}, so case is ignored.
+The @var{value_ptr} is set to the address of the value found,
+and @var{value_size_ptr} is set to the number of bytes in the
+value.
@end deftypefun
@@ -1787,7 +1904,7 @@
@section Enqueuing a response
-@deftypefun int MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
+@deftypefun enum MHD_Result MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
Queue a response to be transmitted to the client as soon as possible
but only after MHD_AccessHandlerCallback returns. This function
checks that it is legal to queue a response at this time for the
@@ -1915,6 +2032,21 @@
@end deftypefun
+@deftypefun {struct MHD_Response *} MHD_create_response_from_pipe (uint64_t size, int fd)
+Create a response object. The response object can be extended with
+header information and then it can be used ONLY ONCE.
+
+@table @var
+@item fd
+file descriptor of the read-end of the pipe; will be
+closed when response is destroyed.
+The descriptor should be in blocking-IO mode.
+@end table
+
+Return @code{NULL} on error (i.e. out of memory).
+@end deftypefun
+
+
@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (size_t size, int fd, off_t offset)
Create a response object. The response object can be extended with
header information and then it can be used any number of times.
@@ -1984,6 +2116,24 @@
@end deftypefun
+@deftypefun {struct MHD_Response *} MHD_create_response_from_buffer_with_free_callback (size_t size, void *data, MHD_ContentReaderFreeCallback crfc)
+Create a response object. The buffer at the end must be free'd
+by calling the @var{crfc} function.
+
+@table @var
+@item size
+size of the data portion of the response;
+
+@item buffer
+the data itself;
+
+@item crfc
+function to call at the end to free memory allocated at @var{buffer}.
+@end table
+
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
+
@deftypefun {struct MHD_Response *} MHD_create_response_from_data (size_t size, void *data, int must_free, int must_copy)
Create a response object. The response object can be extended with
header information and then it can be used any number of times.
@@ -2025,6 +2175,28 @@
@end example
+@deftypefun {struct MHD_Response *} MHD_create_response_from_iovec (const struct MHD_IoVec *iov, int iovcnt, MHD_ContentReaderFreeCallback crfc, void *cls)
+Create a response object from an array of memory buffers.
+The response object can be extended with header information and then be used
+any number of times.
+@table @var
+@item iov
+the array for response data buffers, an internal copy of this will be made; however, note that the data pointed to by the @var{iov} is not copied and must be preserved unchanged at the given locations until the response is no longer in use and the @var{crfc} is called;
+
+@item iovcnt
+the number of elements in @var{iov};
+
+@item crfc
+the callback to call to free resources associated with @var{iov};
+
+@item cls
+the argument to @var{crfc};
+@end table
+
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
+
+
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -2033,7 +2205,7 @@
@section Adding headers to a response
-@deftypefun int MHD_add_response_header (struct MHD_Response *response, const char *header, const char *content)
+@deftypefun enum MHD_Result MHD_add_response_header (struct MHD_Response *response, const char *header, const char *content)
Add a header line to the response. The strings referenced by
@var{header} and @var{content} must be zero-terminated and they are
duplicated into memory blocks embedded in @var{response}.
@@ -2041,12 +2213,23 @@
Notice that the strings must not hold newlines, carriage returns or tab
chars.
+MHD_add_response_header() prevents applications from setting a
+``Transfer-Encoding'' header to values other than ``identity'' or
+``chunked'' as other transfer encodings are not supported by MHD. Note
+that usually MHD will pick the transfer encoding correctly
+automatically, but applications can use the header to force a
+particular behavior.
+
+MHD_add_response_header() also prevents applications from setting a
+``Content-Length'' header. MHD will automatically set a correct
+``Content-Length'' header if it is possible and allowed.
+
Return @code{MHD_NO} on error (i.e. invalid header or content format or
memory allocation error).
@end deftypefun
-@deftypefun int MHD_add_response_footer (struct MHD_Response *response, const char *footer, const char *content)
+@deftypefun enum MHD_Result MHD_add_response_footer (struct MHD_Response *response, const char *footer, const char *content)
Add a footer line to the response. The strings referenced by
@var{footer} and @var{content} must be zero-terminated and they are
duplicated into memory blocks embedded in @var{response}.
@@ -2064,7 +2247,7 @@
-@deftypefun int MHD_del_response_header (struct MHD_Response *response, const char *header, const char *content)
+@deftypefun enum MHD_Result MHD_del_response_header (struct MHD_Response *response, const char *header, const char *content)
Delete a header (or footer) line from the response. Return @code{MHD_NO} on error
(arguments are invalid or no such header known).
@end deftypefun
@@ -2075,7 +2258,7 @@
@section Setting response options
-@deftypefun int MHD_set_response_options (struct MHD_Response *response, enum MHD_ResponseFlags flags, ...)
+@deftypefun enum MHD_Result MHD_set_response_options (struct MHD_Response *response, enum MHD_ResponseFlags flags, ...)
Set special flags and options for a response.
Calling this functions sets the given flags and options for the response.
@@ -2155,7 +2338,7 @@
have been created with the following function:
-@deftypefun int MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
+@deftypefun enum MHD_Result MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
Create a response suitable for switching protocols. Returns @code{MHD_YES} on success. @code{upgrade_handler} must not be @code{NULL}.
When creating this type of response, the ``Connection: Upgrade''
@@ -2196,7 +2379,7 @@
@end deftypefn
-@deftypefun int MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action, ...)
+@deftypefun enum MHD_Result MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action, ...)
Perform special operations related to upgraded connections.
@table @var
@@ -2217,6 +2400,10 @@
@table @code
@item MHD_UPGRADE_ACTION_CLOSE
Closes the connection. Must be called once the application is done with the client. Takes no additional arguments.
+@item MHD_UPGRADE_ACTION_CORK_ON
+Enable corking on the underlying socket.
+@item MHD_UPGRADE_ACTION_CORK_OFF
+Disable corking on the underlying socket.
@end table
@end deftp
@@ -2244,7 +2431,7 @@
@code{MHD_USE_THREAD_PER_CONNECTION} should use the
following functions to perform flow control.
-@deftypefun int MHD_suspend_connection (struct MHD_Connection *connection)
+@deftypefun enum MHD_Result MHD_suspend_connection (struct MHD_Connection *connection)
Suspend handling of network data for a given connection. This can
be used to dequeue a connection from MHD's event loop (external
select, internal select or thread pool; not applicable to
@@ -2278,7 +2465,7 @@
@end table
@end deftypefun
-@deftypefun int MHD_resume_connection (struct MHD_Connection *connection)
+@deftypefun enum MHD_Result MHD_resume_connection (struct MHD_Connection *connection)
Resume handling of network data for suspended connection. It is safe
to resume a suspended connection at any time. Calling this function
on a connection that was not previously suspended will result in
@@ -2343,16 +2530,20 @@
@node microhttpd-dauth basic
@section Using Basic Authentication
+@deftypefun {void} MHD_free (void *ptr)
+Free the memory given at @code{ptr}. Used to free data structures allocated by MHD. Calls @code{free(ptr)}.
+@end deftypefun
+
@deftypefun {char *} MHD_basic_auth_get_username_password (struct MHD_Connection *connection, char** password)
Get the username and password from the basic authorization header sent by the client.
Return @code{NULL} if no username could be found, a pointer to the username if found.
-If returned value is not @code{NULL}, the value must be @code{free()}'ed.
+If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
@var{password} reference a buffer to store the password. It can be @code{NULL}.
-If returned value is not @code{NULL}, the value must be @code{free()}'ed.
+If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
@end deftypefun
-@deftypefun {int} MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, const char *realm, struct MHD_Response *response)
+@deftypefun {enum MHD_Result} MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, const char *realm, struct MHD_Response *response)
Queues a response to request basic authentication from the client.
Return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
@@ -2368,15 +2559,57 @@
@node microhttpd-dauth digest
@section Using Digest Authentication
+MHD supports MD5 (deprecated by IETF) and SHA-256 hash algorithms
+for digest authentication. The @code{MHD_DigestAuthAlgorithm} enumeration
+is used to specify which algorithm should be used.
+
+@deftp {Enumeration} MHD_DigestAuthAlgorithm
+Which digest algorithm should be used. Must be used consistently.
+
+@table @code
+@item MHD_DIGEST_ALG_AUTO
+Have MHD pick an algorithm currently considered secure. For now defaults to SHA-256.
+
+@item MHD_DIGEST_ALG_MD5
+Force use of (deprecated, ancient, insecure) MD5.
+
+@item MHD_DIGEST_ALG_SHA256
+Force use of SHA-256.
+
+@end table
+@end deftp
+
+
@deftypefun {char *} MHD_digest_auth_get_username (struct MHD_Connection *connection)
Find and return a pointer to the username value from the request header.
Return @code{NULL} if the value is not found or header does not exist.
-If returned value is not @code{NULL}, the value must be @code{free()}'ed.
+If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
+@end deftypefun
+
+@deftypefun int MHD_digest_auth_check2 (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
+Checks if the provided values in the WWW-Authenticate header are valid
+and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
+
+@var{realm} must reference to a zero-terminated string representing the realm.
+
+@var{username} must reference to a zero-terminated string representing the username,
+it is usually the returned value from MHD_digest_auth_get_username.
+
+@var{password} must reference to a zero-terminated string representing the password,
+most probably it will be the result of a lookup of the username against a local database.
+
+@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
+Most of the time it is sound to specify 300 seconds as its values.
+
+@var{algo} which digest algorithm should we use.
@end deftypefun
+
@deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
Checks if the provided values in the WWW-Authenticate header are valid
and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
+Deprecated, use @code{MHD_digest_auth_check2} instead.
+
@var{realm} must reference to a zero-terminated string representing the realm.
@@ -2390,7 +2623,67 @@
Most of the time it is sound to specify 300 seconds as its values.
@end deftypefun
-@deftypefun int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
+
+
+@deftypefun int MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t *digest, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
+Checks if the provided values in the WWW-Authenticate header are valid
+and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
+
+@var{realm} must reference to a zero-terminated string representing the realm.
+
+@var{username} must reference to a zero-terminated string representing the username,
+it is usually the returned value from MHD_digest_auth_get_username.
+
+@var{digest} pointer to the binary MD5 sum for the precalculated hash value ``userame:realm:password''. The size must match the selected @var{algo}!
+
+@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
+Most of the time it is sound to specify 300 seconds as its values.
+
+@var{algo} digest authentication algorithm to use.
+@end deftypefun
+
+@deftypefun int MHD_digest_auth_check_digest (struct MHD_Connection *connection, const char *realm, const char *username, const unsigned char digest[MHD_MD5_DIGEST_SIZE], unsigned int nonce_timeout)
+Checks if the provided values in the WWW-Authenticate header are valid
+and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
+Deprecated, use @code{MHD_digest_auth_check_digest2} instead.
+
+@var{realm} must reference to a zero-terminated string representing the realm.
+
+@var{username} must reference to a zero-terminated string representing the username,
+it is usually the returned value from MHD_digest_auth_get_username.
+
+@var{digest} pointer to the binary MD5 sum for the precalculated hash value ``userame:realm:password'' of @code{MHD_MD5_DIGEST_SIZE} bytes.
+
+@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
+Most of the time it is sound to specify 300 seconds as its values.
+@end deftypefun
+
+
+@deftypefun enum MHD_Result MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthAlgorithm algo)
+Queues a response to request authentication from the client,
+return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
+
+@var{realm} must reference to a zero-terminated string representing the realm.
+
+@var{opaque} must reference to a zero-terminated string representing a value
+that gets passed to the client and expected to be passed again to the server
+as-is. This value can be a hexadecimal or base64 string.
+
+@var{response} a response structure to specify what shall be presented to the
+client with a 401 HTTP status.
+
+@var{signal_stale} a value that signals "stale=true" in the response header to
+indicate the invalidity of the nonce and no need to ask for authentication
+parameters and only a new nonce gets generated. @code{MHD_YES} to generate a new
+nonce, @code{MHD_NO} to ask for authentication parameters.
+
+@var{algo} which digest algorithm should we use. The same algorithm
+must then be selected when checking digests received from clients!
+
+@end deftypefun
+
+
+@deftypefun enum MHD_Result MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
Queues a response to request authentication from the client,
return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
@@ -2430,23 +2723,27 @@
const char *realm = "test@@example.com";
int ret;
- username = MHD_digest_auth_get_username(connection);
+ username = MHD_digest_auth_get_username (connection);
if (username == NULL)
@{
response = MHD_create_response_from_buffer(strlen (DENIED),
DENIED,
MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_auth_fail_response(connection, realm,
- OPAQUE,
- response,
- MHD_NO);
+ ret = MHD_queue_auth_fail_response2 (connection,
+ realm,
+ OPAQUE,
+ response,
+ MHD_NO,
+ MHD_DIGEST_ALG_SHA256);
MHD_destroy_response(response);
return ret;
@}
- ret = MHD_digest_auth_check(connection, realm,
- username,
- password,
- 300);
+ ret = MHD_digest_auth_check2 (connection,
+ realm,
+ username,
+ password,
+ 300,
+ MHD_DIGEST_ALG_SHA256);
free(username);
if ( (ret == MHD_INVALID_NONCE) ||
(ret == MHD_NO) )
@@ -2456,16 +2753,21 @@
MHD_RESPMEM_PERSISTENT);
if (NULL == response)
return MHD_NO;
- ret = MHD_queue_auth_fail_response(connection, realm,
- OPAQUE,
- response,
- (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
+ ret = MHD_queue_auth_fail_response2 (connection,
+ realm,
+ OPAQUE,
+ response,
+ (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO,
+ MHD_DIGEST_ALG_SHA256);
MHD_destroy_response(response);
return ret;
@}
- response = MHD_create_response_from_buffer (strlen(PAGE), PAGE,
+ response = MHD_create_response_from_buffer (strlen(PAGE),
+ PAGE,
MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response(response);
return ret;
@}
@@ -2602,7 +2904,7 @@
@end deftypefun
-@deftypefun int MHD_post_process (struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
+@deftypefun enum MHD_Result MHD_post_process (struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
Parse and process @code{POST} data. Call this function when @code{POST}
data is available (usually during an @code{MHD_AccessHandlerCallback})
with the @var{upload_data} and @var{upload_data_size}. Whenever
@@ -2625,7 +2927,7 @@
@end deftypefun
-@deftypefun int MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
+@deftypefun enum MHD_Result MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
Release PostProcessor resources. After this function is being called,
the PostProcessor is guaranteed to no longer call its iterator. There
is no special call to the iterator to indicate the end of the post processing
@@ -2742,7 +3044,7 @@
@section Obtaining state information about a connection
-@deftypefun {const union MHD_ConnectionInfo *} MHD_get_connection_info (struct MHD_Connection *daemon, enum MHD_ConnectionInfoType infoType, ...)
+@deftypefun {const union MHD_ConnectionInfo *} MHD_get_connection_info (struct MHD_Connection *connection, enum MHD_ConnectionInfoType infoType, ...)
Obtain information about the given connection.
@table @var
@@ -2991,6 +3293,9 @@
@code{MHD_post_process()}, @code{MHD_destroy_post_processor()}
can be used.
+@item MHD_FEATURE_SENDFILE
+Get whether @code{sendfile()} is supported.
+
@end table
@end deftp
@@ -3047,11 +3352,16 @@
@cindex license
@include lgpl.texi
-@node GNU GPL with eCos Extension
-@unnumbered GNU GPL with eCos Extension
+@node eCos License
+@unnumbered eCos License
@cindex license
@include ecos.texi
+@node GNU-GPL
+@unnumbered GNU General Public License
+@cindex license
+@include gpl-2.0.texi
+
@node GNU-FDL
@unnumbered GNU-FDL
@cindex license
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/libmicrohttpd_performance_data.eps
^
|
@@ -0,0 +1,8468 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: (ImageMagick)
+%%Title: (libmicrohttpd_performance_data.eps)
+%%CreationDate: (2014-02-19T07:16:22+01:00)
+%%BoundingBox: -0 -0 640 480
+%%HiResBoundingBox: 0 0 640 480
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 1
+%%Pages: 1
+%%EndComments
+
+%%BeginDefaults
+%%EndDefaults
+
+%%BeginProlog
+%
+% Display a color image. The image is displayed in color on
+% Postscript viewers or printers that support color, otherwise
+% it is displayed as grayscale.
+%
+/DirectClassPacket
+{
+ %
+ % Get a DirectClass packet.
+ %
+ % Parameters:
+ % red.
+ % green.
+ % blue.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ compression 0 eq
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/DirectClassImage
+{
+ %
+ % Display a DirectClass image.
+ %
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { DirectClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayDirectClassPacket } image
+ } ifelse
+} bind def
+
+/GrayDirectClassPacket
+{
+ %
+ % Get a DirectClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % red
+ % green
+ % blue
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 eq
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/GrayPseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 eq
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ compression 0 eq
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassImage
+{
+ %
+ % Display a PseudoClass image.
+ %
+ % Parameters:
+ % class: 0-PseudoClass or 1-Grayscale.
+ %
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ class 0 gt
+ {
+ currentfile buffer readline pop
+ token pop /depth exch def pop
+ /grays columns 8 add depth sub depth mul 8 idiv string def
+ columns rows depth
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { currentfile grays readhexstring pop } image
+ }
+ {
+ %
+ % Parameters:
+ % colors: number of colors in the colormap.
+ % colormap: red, green, blue color packets.
+ %
+ currentfile buffer readline pop
+ token pop /colors exch def pop
+ /colors colors 3 mul def
+ /colormap colors string def
+ currentfile colormap readhexstring pop pop
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { PseudoClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayPseudoClassPacket } image
+ } ifelse
+ } ifelse
+} bind def
+
+/DisplayImage
+{
+ %
+ % Display a DirectClass or PseudoClass image.
+ %
+ % Parameters:
+ % x & y translation.
+ % x & y scale.
+ % label pointsize.
+ % image label.
+ % image columns & rows.
+ % class: 0-DirectClass or 1-PseudoClass.
+ % compression: 0-none or 1-RunlengthEncoded.
+ % hex color packets.
+ %
+ gsave
+ /buffer 512 string def
+ /byte 1 string def
+ /color_packet 3 string def
+ /pixels 768 string def
+
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ x y translate
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ currentfile buffer readline pop
+ token pop /pointsize exch def pop
+ /Times-Roman findfont pointsize scalefont setfont
+ x y scale
+ currentfile buffer readline pop
+ token pop /columns exch def
+ token pop /rows exch def pop
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ currentfile buffer readline pop
+ token pop /compression exch def pop
+ class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
+ grestore
+} bind def
+%%EndProlog
+%%Page: 1 1
+%%PageBoundingBox: 0 0 640 480
+userdict begin
+DisplayImage
+0 0
+640 480
+12
+640 480
+1
+0
+0
+102
+FFFFFF
+000000
+A0A0A0
+FF0000
+00C000
+0080FF
+C000FF
+00EEEE
+C04000
+C8C800
+4169E1
+FFC020
+008040
+C080FF
+306080
+8B0000
+408000
+FF80FF
+7FFFD4
+A52A2A
+FFFF00
+40E0D0
+000000
+1A1A1A
+333333
+4D4D4D
+666666
+7F7F7F
+999999
+B3B3B3
+C0C0C0
+CCCCCC
+E5E5E5
+FFFFFF
+F03232
+90EE90
+ADD8E6
+F055F0
+E0FFFF
+EEDD82
+FFB6C1
+AFEEEE
+FFD700
+00FF00
+006400
+00FF7F
+228B22
+2E8B57
+0000FF
+00008B
+191970
+000080
+0000CD
+87CEEB
+00FFFF
+FF00FF
+00CED1
+FF1493
+FF7F50
+F08080
+FF4500
+FA8072
+E9967A
+F0E68C
+BDB76B
+B8860B
+F5F5DC
+A08020
+FFA500
+EE82EE
+9400D3
+DDA0DD
+905040
+556B2F
+801400
+801414
+804014
+804080
+8060C0
+8060FF
+808000
+FF8040
+FFA040
+FFA060
+FFA070
+FFC0C0
+FFFF80
+FFFFC0
+CDB79E
+F0FFF0
+A0B6CD
+C1FFC1
+CDC0B0
+7CFF40
+A0FF20
+BEBEBE
+BFBFBF
+5F5F5F
+1F1F1F
+DFDFDF
+9F9F9F
+3F3F3F
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001010101010101010100010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000606101010000000000006361010161630000000000636101016163000000
+0063610101616300000000000000000000000000000000000000000000000000606101010000
+0000000000636101016163000000006361010161630000000063610101616300000000636101
+0161630000000063610101616300000000006361010161630000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000161000000000000006101
+0000010000000000000000010000000101010162651B63000000000100000000000000000000
+0000000000000001000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000010000000001010101010101010000
+0000000000000060650162616300000000010101010101000000006361010161630000000000
+00631B6562016261600000000000606162016265640000000000006361620101626160000001
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000621B6301000000000000621B63631B620000000000621B63631B6200000000621B63631B
+6200000000000000000000000000000000000000000000000000621B63010000000000000062
+1B63631B6200000000621B63631B6200000000621B63631B6200000000621B63631B62000000
+00621B63631B620000000000621B63631B620000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000162630000000000636501000001000000
+0000000000010000000100000063601B62640000000100000000000000000000000000000000
+0001000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000010000000000000000000000000000000000
+000000000000000000000000000000000001000000000000000000001B610000000000000000
+606264636364650000000001000000000000000000621B63631B620000000000606261606300
+631B621B00000000656463006360651B00000000646264630063646501000001000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000001
+00000000001B610000000061640000001B6100000000616400001B6100000000616400000000
+0000000000000000000000000000000000000000000000010000000000001B61000000006164
+00001B6100000000616400001B6100000000616400001B6100000000616400001B6100000000
+61640000001B6100000000616400000100000000000000000000000000000000000000000000
+000000000000000000000000000000011B610000000000616401000001000000000000000001
+0000000100000000000060626300000100000000000000000000000000000000000100000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000062600000000000000000656400000000
+64640000000100000000000000001B6100000000616400000064626000000000000000656100
+000000000000000063010000006362630000000000001B000001000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000001000000000001001B620162640000000001006162010000606501
+626400000000006065016264000000000000000000010000000000636101621B000000010061
+6201656300000000000000000000000000000000636162016264000000000001000000000065
+6000000000606500000065600000000060650000656000000000606500000000000000000000
+00000001001B6201626400000000000000010000000000006560000000006065000065600000
+0000606500006560000000006065000065600000000060650000656000000000606500000065
+60000000006065000001000000000000006362000000000000006260001B6201016560000000
+0000000000000000000163626300000063620001000001000000000000000001000000010000
+00000000001B6100000100000000001B62010165600000000000000100000000010061620165
+630000000060650162640000000001001B6201626400000000636162016264000001001B6201
+626400000001006162621B00006162016100000000636101621B000000000100616201000001
+0000000060626400010000000000000000000060650101656000000001001B62016264000000
+0000000000010000000000000000006065000000000000000000016300000000636500000001
+0000000000000000656000000000606500006362600060650101656001006260000000000000
+0000636200000061640000000000000000000001000000000000000001000001010101010101
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000001000000000001611B630060626400000001616400000063626400606260000000
+63626400606260000000000000000000000000000062640063611B0000016164636364626300
+0000000000000000000000000063621B63006061000000000001000000000062630000000063
+620000006263000000006362000062630000000063620000000000000000000000000001611B
+6300606264000000000000010000000000006263000000006362000062630000000063620000
+6263000000006362000062630000000063620000626300000000636200000062630000000063
+62000000000000000000000061640000000000646500611B6300636065000000000000000000
+0000000100611B0000001B1B0001000001000000000000000001000000010000000000000063
+6200000000000000611B63006360650000000000000000000000016164636364626300006362
+640060626000000001611B6300606264000063621B63006061000001611B6300606264000001
+61646363651B61646363656400000062640063611B0000000161640000000001000000606260
+0000000000000000000000006062646363646260000001611B63006062640000000000000001
+0000000000000000006564000000000000000000016300000000636200000001620162616300
+0000626300000000636200001B610060626463636401010064610000000000000060651B0000
+0062630000000000000000000001000000000000000001000000000000001B62000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000011B000000006065000000011B00000000611B0000006065000000611B00000060
+6500000000000000000000000000000000000063620000011B000000001B6100000000000000
+00000000000000611B0000000000000000000001000000000001000000000000010000000100
+0000000000010000010000000000000100000000000000000000000000011B00000000606500
+0000000000010000000000000100000000000001000001000000000000010000010000000000
+0001000001000000000000010000010000000000000100000001000000000000010000000000
+0000000000006062000000000062600001000000000000000000000000000000000000010063
+6200000062630001000001010101010101010101000000010000000000000000010000000000
+0000010000000000000000000000000000000000011B000000001B610000611B000000606500
+0000011B0000000060650000611B00000000000000011B000000006065000001640000006001
+640000006065000000000000006362000000011B000000000001000064656300000000000000
+00000000000061640000000064610000011B0000000060650000000000000001000000000000
+00006362000000000000000000006564000000006401000000656000631B6260000001000000
+0000000100006260006564000000006401006362000000000101010165000000000100000000
+0000000000000001010101010101010101000000000000646263000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000001
+6300000000636200000001630000000062630000006362000000626300000063620000000000
+0000000000000000001B62010101010000016300000000636200000000000000000000000000
+0062630000000000000000000001000000000001000000000000010000000100000000000001
+0000010000000000000100000000000000000000000000016300000000636200000000000001
+0000000000000100000000000001000001000000000000010000010000000000000100000100
+0000000000010000010000000000000100000001000000000000010000000000000000000000
+0065640000001B65000065616300000000000000000000000000000000010000656400646100
+0001000001000000000000000001000000010000000000000000010000000000000065616300
+0000000000000000000000000000016300000000636200006263000000636200000001630000
+0000636200006263000000000000000163000000006362000001630000000001630000000001
+0000001B62010101010000000163000000000001001B61000000000000000000000000000000
+62630000000063620000016300000000636200000000000000010000000000000000611B0000
+0000000000000000606264636364620100000000000000006465000001000000000000010000
+01000001630000000063010000010000000000006364621B0000000100000000000101010100
+0001000000000000000001000000000060626300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000001000000000000
+0100000001000000000001010101010101000000010101010101010000000000000000000000
+0000616560000000010000010000000000000100000000000000000101010100000100000000
+0000000000000001000000000062630000000063620000006263000000006362000062630000
+0000636200000000000000010101010000010000000000000100000000000001000000000000
+6263000000006362000062630000000063620000626300000000636200006263000000006362
+0000626300000000636200000062630000000063620000000000000000000000006062000000
+6264000063610162616000000000000000000000000000010000606200626000000100000100
+0000000000000001000000010000000000000063620000000000000063610162616000000000
+0000000000000000010000000000000100000101010101010100000001000000000000010000
+0100000000000000000100000000000001000001000000000001000000000001000061656000
+0000010000000100000000000001006263000000000000000000000000000000010000000000
+0001000001000000000000010000000000000001000000000000006362630000000001010101
+0000006065010165646200000000000000006301000062630000000063620000010000016300
+0000006301006362000000000000000060620000006263000000000000000100000100000000
+0000000001000000006062600000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000001000000000000010000000100
+0000000062630000000000000000626300000000000000000000000000000000000062630000
+0063010000016300000000636200000000000000000000000000006263000000000000000000
+0001000000000065600000000060650000006560000000006065000065600000000060650000
+0000000000000000000000010000000000000100000000000001000000000000656000000000
+6065000065600000000060650000656000000000606500006560000000006065000065600000
+00006065000000656000000000606500000000000000000000000000651B001B620000000000
+006364656100000000000000000000000001000000621B620000000100000100000000000000
+000100000001000000000000001B610000000000000000000063646561000000000000000000
+0000016300000000636200006263000000000000000001000000000000010000626300000000
+0000000100000000000001000001000000000001000000000001000062630000006301000000
+0100000000000001006462630000000000000000000000000000626300000000636200000100
+0000000000010000000000000001000000000000001B61000000000000000000000000000000
+0000606100000000000000006301000065600000000060650000626000656400000000640100
+646100000000000000000001000000611B000000000000000100000100000000000000000100
+0000636260000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000001000000000000010000000100000000006164
+0000000000000000616400000000000000000000000000000000000062630000001B01000001
+1B000000001B610000000000000000000000000000611B000000000000000000000100000000
+001B610000000061640000001B6100000000616400001B610000000061640000000000000000
+00000000000100000000000001000000000000010000000000001B6100000000616400001B61
+00000000616400001B6100000000616400001B6100000000616400001B610000000061640000
+001B610000000061640000000000000000000000000064016301640000000000000000630100
+0000000000000000000000010000006401640000000100000100000000000000000100000001
+00000000000063626300000000000000000000000063010000000000000000000000011B0000
+00001B6100006164000000000000000001000000000000010000611B00000000000000010000
+0000000001000001000000000001000000000001000062630000001B01000000010000000000
+0001000060626000000000000000000000000000616400000000646100000100000000000001
+0000000000000001000000000000006263000000000000000000000000000000000065600000
+000000000000646500001B6100000000616400001B6100606264636364620160626300000000
+0000000060620000006362630000000000000100000100000000000000000100006362640000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000001000000000000010000000100000000006362646300606500
+00006362646300606500000000000000000000000000616163631B6101000001616463636462
+63000000000000000000000000000063621B63006061000000000001000000000000621B6363
+1B620000000000621B63631B6200000000621B63631B62000000000000000000000000000001
+000000000000010000000000000100000000000000621B63631B6200000000621B63631B6200
+000000621B63631B6200000000621B63631B6200000000621B63631B620000000000621B6363
+1B620000000000000000000000000000006262620000000065646300631B6500000100000000
+000000000001000000000000000000010000010000000000000000010000000100000063601B
+6264000000000000000065646300631B65000000000000000000000001616463636462630000
+636264630060650000000100000000000001000063621B630060610000010000000000000100
+00010000000000010000000000010000616163631B6101000000010000000000000100000060
+6264000000000000000000000000606264636364626000000100000000000001000000000000
+000100000000000064650000000000000000000000000065600063616100000065646300631B
+6260000000621B63631B62000000636260006065010165600165630000006560630063646260
+0000000064621B630000631B010000010000000000000000010000621B000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000001000000000000010000000100000000000060650101656000000000606501
+0165600000000000000000000000000063616201610001000001006162016563000000000000
+0000000000000000000063616201656400000101010101010100000063610101616300000000
+0063610101616300000000636101016163000000000000000000000000000001000000000000
+0100000001010101010101000000006361010161630000000063610101616300000000636101
+0161630000000063610101616300000000636101016163000000000063610101616300000000
+00000000000000000000006401640000000060616201621B0000000100000000000000000001
+000000000000000000010000010000000000000000010000000101010162651B630000000000
+0000000060616201621B00000000000000000000000001006162016563000000006065010165
+6000000001000000000000010000006361620165640000010000000000000100000100000000
+000100000000000100006361620161000100000001000000000000010000000063621B000000
+0000000000000000006465010165600000000100000000000001000000000000000100000000
+0000656000000000000000000000000000646201626400000000606162016261630000000063
+6101016163000000006462600000000000000000000000006061620162616000000000000060
+6162010162616300000100000000000000000100000101010101010100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000060626160630063606165000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+1B65620101651B63000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000606101010000000000000000000000
+0000000000000000000000000000000000006361010161630000000000646201626400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000621B63010000000000000000000000000000000000
+000000000000000000000000621B63631B620000000061616300606500000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+00000000001B6100000000616400006065000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000006065016264000000000000000000010000000000000065
+6000000000606500006160000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000636264006062600000000000000000010000000000000062630000000063
+6200006264650101656000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000611B00000060650000000000000000010000000000000001000000000000010000016264
+6363646260000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000062630000
+0063620000000000000000010000000000000001000000000000010000016400000000646500
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000001010101010101000000
+0001010101010101010100000062630000000063620000626300000000630100000000000000
+0000000000000000000101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000062630000000000000000000000000001
+0000000000000065600000000060650000656300000000630100000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000010000000000000000000100000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000010000
+0000000000000100000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000010000000000000000000100000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0100000000000000000100000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000100000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000061640000000000000000000000000001000000000000
+001B610000000061640000646400000000646500000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000010000000000000000000100000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000010000000000000000
+0100000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000010000000000000000000100000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000010000000000
+0000000100000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000100000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000010000000000636264630060650000000000000000010000000000000000621B6363
+1B62000000006564636364626000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000101010101
+0101000000606501016560000000000000000001000000000000000063610101616300000000
+6361620165600000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010101000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000016263000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000101
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+6465000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001006564000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001006362630000000001000060
+6501016560000000000000000000606501626400000000010061620165630000000000606501
+0165600000010000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000100001B610000000001006062646363646260
+0000000000000063626400606260000000016164636364626300000060626463636462600001
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000656000000001006164000000006461000000000000
+00611B0000006065000000011B000000001B6100000061640000000064610001000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000636200000001006263000000006362000000000000006263000000
+6362000000016300000000636200000062630000000063620001000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000001B1B000001000100000000000001000000000000000101010101010100000001
+0000000000000100000001000000000000010001000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0065630001006263000000006362000000000000006263000000000000000001630000000063
+6200000062630000000063620001000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000006065000100
+61640000000064610000000000000061640000000000000000011B000000001B610000006164
+0000000064610001000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000010000000000001B640100606264636364
+6260000000000000006362646300606500000001616463636462630000006062646363646260
+0001000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000650100006465010165600000000000
+0000000060650101656000000001006162016563000000000064650101656000000100000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000101010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010101000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000000000004000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040000000400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400040000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000006200000000006301630000
+0000006201000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000040004000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000006164000000006401640000000064650100
+0000010000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004000000040000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000606100000000611B610000000061640000000001000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400000400000400000400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000006200000000626362000000636200010000010101010100000001001B
+6201626400000000000000000060650162640000000001006162016563000000006065010165
+6000000001000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000000040004000000000004000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000001B64000063650065630000646100010000000100000000000001611B630060626400
+0000000000006362640060626000000001616463636462630000606264636364626000000100
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000400000000000400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040004000000040000000400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000006065
+00006461001B6400006560000100000001000000000000011B00000000606500000000000000
+611B0000006065000000011B000000001B610000616400000000646100000100000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000400
+0000040000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400000000000400040000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000062630061640060
+6100636200000100000001000000000000016300000000636200000000000000626300000063
+6200000001630000000063620000626300000000636200000100000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000400000000
+0004000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000001B1B006263006362001B1B0000
+0100000001000000000000010000000000000100000000000000010101010101010000000100
+0000000000010000010000000000000100000100000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000400000004000000040004000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000063656362000000626362630000010000000100
+0000000000010000000000000100000000000000626300000000000000000163000000006362
+0000626300000000636200000100000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000004000400000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040000000000040004000000040000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000651B61000000611B65000000010000000100000000000001
+000000000000010000000000000061640000000000000000011B000000001B61000061640000
+0000646100000100000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000400000004000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000400000000000400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000064016400000064011B000000010000006264000000000001000000000000
+0100000000000000636264630060650000000161646363646263000060626463636462600000
+0100000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000040000000000040000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000630163000000630163000000010000006062010100000001000000000000010000000000
+0000006065010165600000000100616201656300000000646501016560000000010000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040000000000040000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010101000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000400000004000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001010100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040000
+0000000400000000000000000004000400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000400000004000000
+0000000000000000040000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004000400000000000000000000
+0004000400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000040000000000000000000000040000000400
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004000400000000000000000004000000000004000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400000004000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0000000000040000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000040000000000040000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400000004000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000606101
+0100000000000063610101616300000000636101016163000000006361010161630000000000
+6361010161630000000063610101616300000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000400000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000621B63010000000000
+00621B63631B6200000000621B63631B6200000000621B63631B620000000000621B63631B62
+00000000621B63631B6200000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000100000000001B6100000000
+616400001B6100000000616400001B610000000061640000001B6100000000616400001B6100
+0000006164000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000400
+0400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000656000000000606500006560
+0000000060650000656000000000606500000065600000000060650000656000000000606500
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040000000400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000626300000000636200006263000000006362
+0000626300000000636200000062630000000063620000626300000000636200000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004000000000004000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000010000000000000100000100000000000001000001000000
+0000000100000001000000000000010000010000000000000100000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000400000000000400000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000010000000000000100000100000000000001000001000000000000010000
+0001000000000000010000010000000000000100000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000000040000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000626300000000636200006263000000006362000062630000000063620000006263000000
+0063620000626300000000636200000000000000000000000000000000010101010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010101010100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000065600000
+0000606500006560000000006065000065600000000060650000006560000000006065000065
+6000000000606500000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000000000004
+0000000000000000000000000000000000000000000000000000000000000000000004040000
+0000040000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000100000000001B610000000061640000
+1B6100000000616400001B610000000061640000001B6100000000616400001B610000000061
+6400000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040000000400000000000000
+0000000000000000000000000000000000000000000000000000000004040400000400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000621B63631B6200000000621B63631B
+6200000000621B63631B620000000000621B63631B6200000000621B63631B62000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400040000000000000000000000000000
+0000000000000000000000000000000000000400000400000404040000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001010101010101000000636101016163000000006361010161630000000063
+6101016163000000000063610101616300000000636101016163000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000000000000000000000000000000000000000000
+0000000000000000000000000004040000040004040000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000400040000000000000000000000000000000000000000000004000000
+0000040000000000040004000400040000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040000000400000000000000000000000000000000000000000000040000000400000000
+0000000400040000000400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000101010000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000621B6300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000000000404000000
+0004000000000000000000000000000000000000000000000400040000000000000004000400
+0000000004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000063610161600000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040000000400000000000000000000
+0000000000000000000000000000000000000004000000000000000400000004000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000631B626564000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000400040000000000000000000000000000000000
+0000000000000000000000000400040000000000040000000000040000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000006465621B63000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004000000000000000000000000000000000000000000000000
+0000000000040000000400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000001B0101610000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400040000000000000000000000000000000000000000000000000000000400
+0000000004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000063
+1B626560001B6100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0000000400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000636162616300000063
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000400000000000400
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000006065621B63000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004000000000004000004000000
+0000040000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006564000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000040000000400000000040000000400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400040000000000000400040000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000006461000000000061640000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000000000000000004000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000626000
+0000000060650000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010101
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000400040000000000000400040000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001010100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000004000000
+0400000000040000000400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000626300000000006362000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000400000000000400000400
+0000000004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000611B00000000001B61000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+000000000000000000000063621B6300631B6263000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000006361620162616300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000400
+0000000004000000000000000000000000000000000004000000000004000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000000040000
+0000000000000000000000000000000000040000000400040000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000646562010101010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040004000000000000000000
+0000000000000000000000000400040004000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000064626063000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400000000000400000000000000000000
+0000000000000004000400000004000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000062600000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000040004000000040000000000000000000000000004000000
+0400040000000400000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000000040004000000000000000000000000000000040004000400040004
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0062630000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400000000000400000000000000000000000000000000000400040000000400000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000001B1B000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0004000000000000000004000000000004000004000000040004000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000611B6300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000400000004000000
+0000000000040000000400000400040004000000040000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000101010101010101010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040000000000040000000000000000
+0400040000040000000400000000000400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000400000400
+0000000004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040004000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000004000000040000000000000400000000000400
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000006065
+6201000065600000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000400000000000400000000000004000000040000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000646260630100006065
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040000000000040000040004000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000626000000100000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400000004000000000400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000100006301000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004000400000000040004000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000656400000100006465000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000004000000
+0004000000040004000000000004000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+000000000060621B630163646263000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400000000000400040000040000000000
+0400040000000400000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+6361620162616300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0101000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000400000000
+0004000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000000040000000400000000000000040000040004
+0400000400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000101010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000000040000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040004000000000004000000000000000400000404000004000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040004000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040400000000040000000000000000000004040404000400000400000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000400000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0404000004000000000000000000000004040004040000040000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030003030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040004000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000400000404040000
+0000000400000004000404000404040404000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000004000000040000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040000000004040000000000000400
+0000040400000404000404000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000030303
+0303030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000646200000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040000
+0000000400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400040000000000000004000404040004
+0004040004040004000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003030303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001010101010101
+0101626000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000040000000400000000000000040000000400000404000004
+0400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030303030303030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000000000004000000000004040400040004040000040004040000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030303030303030303030303030303030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000400000404000004040000000400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003030303030303030303030303030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000001B620101010101010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040004000404040404000400040004000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030303030303030303030303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000001B61630100631B61000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000060610101000000000000636101016163
+0000000063610101616300000000636101016163000000000063610101616300000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040000040400000004000000040000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0303030000000000030303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000006263000100000064610000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000621B6301000000000000621B63631B6200000000621B
+63631B6200000000621B63631B620000000000621B63631B6200000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040404
+0400000400000000000400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303030303030000000000
+0000000003030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0100000000620000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000100000000001B6100000000616400001B6100000000616400
+001B610000000061640000001B61000000006164000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040400000400000400
+0000040404000000040404000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000303030303030300000000000000000000000303
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000616400626000006362
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000065600000000060650000656000000000606500006560000000
+0060650000006560000000006065000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040004000004000004000400040404
+0004040404000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000303030303030300000000000000000000000003030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+00000000000000000000000000000000000000000000006362001B6563636161000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000062630000000063620000626300000000636200006263000000006362000000
+6263000000006362000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000000040000000004040004000404040404040000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000030303030303030000000000000000000000000000030303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000006162626163000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0001000000000000010000010000000000000100000100000000000001000000010000000000
+0001000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000400000000000400000000040400040404040404000004000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000303
+0303030303000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000100000000
+0000010000010000000000000100000100000000000001000000010000000000000100000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000040404040404040404000400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000303030303030300
+0000000000000000000000000000000303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000006263000000006362000062
+6300000000636200006263000000006362000000626300000000636200000000000000000000
+0000000000010101010100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000004040404040404040000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030000000000000000
+0000000000000000000003030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001010101010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000006560000000006065000065600000000060
+6500006560000000006065000000656000000000606500000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400000404040404040004040400040000000000000000000000000000000000000000000000
+0000000000000000000000000000000003030303030303000000000000000000000000000000
+0000000000030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000001B6100000000616400001B6100000000616400001B6100
+00000061640000001B6100000000616400000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000004040000
+0404000400040404000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003030303030303000000000000000000000000000000000000000003
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000001010101010101010101010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000001000000000000621B63631B6200000000621B63631B6200000000621B63631B620000
+000000621B63631B620000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000404000000000404000400
+0400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000303030303030300000000000000000000000000000000000000000000030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010101010101
+0100000063610101616300000000636101016163000000006361010161630000000000636101
+0161630000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000400040004000400040000
+0004000000000000000000000000000000000000000000000000000000000000000003030303
+0303030300000000000000000000000000000000000000000000030303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000400040004000400040004000000
+0000000000000000000000000000000000000000000000000000000000000303030300000000
+0000000000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001010100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040004040404040004040404000000000000000000
+0000000000000000000000000000000000000000000003030303030303000000000000000000
+0000000000000000000000000000000303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010101000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000000040404040404040400000000000000000000000000000000
+0000000000000000000000000000000303030303030303000000000000000000000000000000
+0000000000000000000003030303030303000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000404040404040000040000000000000000000000000000000000000000
+0000000000000000000303030303030300000000000000000000000000000000000000000000
+0000000003030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400040004040404040004000000000000000000000000000000000000000000000000000000
+0000030303030303030000000000000000000000000000000000000000000000000000000003
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000400040404
+0404040400000000000000000000000000000000000000000000000000000000000003030303
+0303030000000000000000000000000000000000000000000000000000000000030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000064656201010101010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040004040404040404040400
+0400000000000000000000000000000000000000000000000000000303030303030303000000
+0000000000000000000000000000000000000000000000000000030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000006462606300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000404000400000404040404000000040000
+0000000000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000006260000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000040004000400040004000400000000000000
+0000000000000000000000000000000303030303030300000000000000000000000000000000
+0000000000000000000000000000000303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004000404040404000404040400000000000000000000000000
+0000000000000000000003030303000000000000000000000000000000000000000000000000
+0000000000000000000303030303030303000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000626300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004040404040404040000000000000000000000000000000000000000
+0000030303030303030000000000000000000000000000000000000000000000000000000000
+0000000003030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+00000000000000000000000000000000000000000000001B1B00000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000400040404040404000004000000000000000000000000000000000000000003030303
+0303030000000000000000000000000000000000000000000000000000000000000000000303
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000611B630000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000004000400
+0404040404000400000000000000000000000000000000000000000303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000003030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010101010101010101000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010101000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040004040404040404
+0000040000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000003030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000101
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004000404040404040404040404000004
+0000000000000000000000000000030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040400040000040404040400040404040000000000
+0000000000000000030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004040404040404040404000000000000000000000000
+0003030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000030303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000606562010000656000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000400000404040404040400000000000000000000000000000000030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000064626063010000606500000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040404040404040000040000000000000000000000030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000062600000010000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000404
+0004040404040404000400000000000000000000000003030300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000010000630100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000400040404040404
+0404040000000000000000000000030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0065640000010000646500000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004040404040404040404040004
+0000000000000003030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000003030303030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000060621B6301
+6364626300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000004000000000404040004000404040000000000
+0003030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000003030303030303000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000063616201626163000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040004040400040404000000000000030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000400040404040400000400000000000003030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0003030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040004000404040000040400000000030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003030303
+0303030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000006265600000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400040404040404040004000000000303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003030303030303030000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000064626564000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000404040004
+0404000400040403030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+1B62626400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040404000004040404000404
+0404030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000030303030303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000001B016264
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000404040404040404040403030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000030303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000636201000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040400040404040404040403030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000001B016264000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040004000404040404040304030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000646265640000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400040404040404030403040403030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0303000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000006462656000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004040404040404040304040404000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000030303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000062
+6160000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000404040404
+0004040404040404000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000063000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040400040304040404
+0400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040004030404040404030004000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003030303030303000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000001010001010101010101010100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001010100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000400040404040404000404000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000101010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004040404040404040400040400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000303
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003040404030404040404040400000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000303030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030403030404040404040004000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000101010101
+0101010162640000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003030304
+0400040404000400000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000611B6300631B61636062
+6400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303030404030404040404
+0000040000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000003030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000006164000000000064610064650000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003030400040404040404000404040400
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006263000000000063620063010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000003030303030304040400040404040404040400000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000163000000000063010000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003030303030303040004000404040404040000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003030303
+0303030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000006564000000000064650060650000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000303000000000400000404040404000004000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003030303030303030000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+000000000000000000000000000000000000000000000000000000000000000000000060621B
+6300631B62630065640000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0300000000040404040404000404000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000006361620162616300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000606101010000000000006361010161630000000063610101
+6163000000006361010161630000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000030303030303030000000404
+0404040404040400040000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000030303030303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000621B6301000000000000621B63631B6200000000621B63631B6200000000
+621B63631B620000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030000000000000404040404040404
+0404040400000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000100000000001B6100000000616400001B6100000000616400001B610000000061
+6400000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000003030303030303000000000004040000040404040404000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000656000000000606500006560000000006065000065600000000060650000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030300000000000000000004040404040400040004000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000062
+6300000000636200006263000000006362000062630000000063620000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030303000000000000000000000404000404040404000404000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0303000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000001000000000000
+0100000100000000000001000001000000000000010000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0300000000000000040400040404040400040404040000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000001000000000000010000010000
+0000000001000001000000000000010000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303030303000000000000
+0000000004040400040404040404040000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000062630000000063620000626300000000636200
+0062630000000063620000000000000000000000000000000001010101010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030000000000000000000000000404
+0004000404040404000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001010101010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000062000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000065600000000060650000656000000000606500006560000000
+0060650000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000303030303030303000000000000000000000000040004040404
+0400000404000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000061640000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000100000000001B6100000000616400001B6100000000616400001B61000000006164000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030300000000000000000000000004000404040404040404040404
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000611B63000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000621B63631B6200000000621B63631B6200000000621B63631B6200000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030303000000000000000000000000000000040404040404040404040400000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000303
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001010101010101010100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000101010101010100000063610101
+6163000000006361010161630000000063610101616300000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000003030303030303
+0000000000000000000000000000000404040404040404040404000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000003030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000303030000000000000000
+0000000000000000000004000004040404040404040400000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000101010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000030303000000000000000000000000000000
+0000000000000404040404040404040400000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010101000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000060616201626160000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000303030303030303000000000000000000000000000000000004
+0404040404040404040400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006062646300636462600000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003030303000000000000000000000000000000000000000000040404040404
+0404040004040000000000000000000000000000000000000000000000000000000000000000
+0000000000000000030303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000006564000000000064650000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000003
+0303030303030000000000000000000000000000000000000000000404040404040400040404
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000163000000000063010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000003030303030303
+0000000000000000000000000000000000000000040404040404040404040400000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000003
+0303000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000016300
+0000000063010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000303030303030300000000000000
+0000000000000000000000000000000404040404040404040004040400000000000000000000
+0000000000000000000000000000000000000000000000000000000000030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000656400000000006465
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000030303000000000000000000000000000000
+0000000000000000000004040400040404040404040000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000646264630063646260000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000303030303030300000000000000000000000000000000000000
+0000000004040004040404040404040404000000000000000000000000000000000000000000
+0000000000000000000000000000000000030303030303030300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000006061620162616000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000030303030303030000000000000000000000000000000000000000000000000000
+0404040404040404040400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0300030300000000000000000000000000000000000000000000000000000004040400040404
+0404040004000000000000000000000000000000000000000000000000000000000000000000
+0000000000000303030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030003030000
+0000000000000000000000000000000000000000000000000000040004040404040404040404
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000003030303000000000000000000
+0000000000000000000000000000000000000000000404040404040404040404000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0303030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000062600001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000030303030303030000000000000000000000000000
+0000000000000000000000000000000000040404040404040400040000000000000000000000
+0000000000000000000000000000000000000000000000000000000303030303030303000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000101010000000000000000000000000000000000
+0000000000000000000000000000000000000000000064620101010101010101010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000030303030303030000000000000000000000000000000000000000
+0000000000000000000004040404040404040404040400000000000000000000000000000000
+0000000000000000000000000000000000000000000003030303030303000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003030303030303030300000000000000000000000000000000000000000000000000
+0000000000000004040404040404040404000000000000000000000000000000000000000000
+0000000000000000000000000000000003030303030303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000003
+0003030300000000000000000000000000000000000000000000000000000000000000000000
+0404040404040404040404040400000000000000000000000000000000000000000000000000
+0000000000000000000003030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000003030303030000
+0000000000000000000000000000000000000000000000000000000000000000040404000404
+0404040404040400000000000000000000000000000000000000000000000000000000000000
+0000000000030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000400040404040404040404
+0400000000000000000000000000000000000000000000000000000000000000000000000003
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000004040404040404040404040000000000
+0000000000000000000000000000000000000000000000000000000000000003030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000404040404040404040404000000000000000000000000
+0000000000000000000000000000000000000000000000000000030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000040404040404040404040004000000000000000000000000000000
+0000000000000000000000000000000000000000030303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000040404040404040404040400040404000000000000000000000000000000000000
+0000000000000000000000000000030303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000006065000000610165000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400040404040404040404040400000000000000000000000000000000000000000000000000
+0000000000000000030303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000656000006465631B1B0000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000404040404
+0404040404040404000000000000000000000000000000000000000000000000000000000000
+0000000303030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000016300
+0061640063620000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000404040404040404
+0404040000000000000000000000000000000000000000000000000000000000000000030303
+0303030303000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000006263000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040404040404040404040404000000
+0000000000000000000000000000000000000000000000000000000000030303030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000626300630100006362000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000404040404040404040404040000000000000000
+0000000000000000000000000000000000000000000000000303030303030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+00000000000000000000000000000000001B1B00616100006461000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000030303
+0303000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040404040404040404040404040004000000000000000000000000
+0000000000000000000000000000000000000303030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000006101656300006560000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003030303030303000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040404040404040404040404000404000000000000000000000000000000000000
+0000000000000000000000000003030303030303000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000303030303030303000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0404040404040404040404040400000000000000000000000000000000000000000000000000
+0000000000000303030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000404040404
+0404040404040004000000000000000000000000000000000000000000000000000000000000
+0303030303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040000040404040404040404
+0404040000000000000000000000000000000000000000000000000000000000000303030303
+0303030303000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040404040404040404040404000000
+0000000000000000000000000000000000000000000000000000000003030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000646200000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000030000000003030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000004040404040404040400040000000000000000
+0000000000000000000000000000000000000000000003030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010101010101010101626000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030003000003030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000404040404040404040404040000000000000000000000000000
+0000000000000000000000000000000000030303030303030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000030303030303030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040004040404040404000400000000000000000000000000000000000000
+0000000000000000000003030303030303030303000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0060650000006101650000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001010100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000030303030303030303000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004000404040404040400040400000000000000000000000000000000000000000000000000
+0000000303030303030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010101000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000006560000064
+65631B1B00000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000004040404
+0404040404040400040000000000000000000000000000000000000000000000000000000000
+0303030303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000163000061640063620000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003030303
+0303030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000404040404040404
+0004000000000000000000000000000000000000000000000000000000000000030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000062630000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004040404040404040404040000
+0000000000000000000000000000000000000000000000000000030303030303030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006263006301000063620000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000300
+0000000000000000000000000000000000000000000303030303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404000404040404040404040400000000000000
+0000000000000000000000000000000000000000000303030303030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000001B1B006161000064610000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000300000000000000
+0000000000000000000000000000030003030303030303030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000400040404040404040404040400000000000000000000000000
+0000000000000000000000000000000003030303030303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000061016563000065600000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000300000000000000000300000000
+0000000000000000030303030303030003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004040404040404040404040000040000000000000000000000000000000000
+0000000000000000000303030303030303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000303030303030300000000000303000300000300000300
+0003030303030303000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0404040004040404040404040004000000000000000000000000000000000000000000000000
+0000000000030303030303030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003000000000300000300000300030303000300000300000303030303030303
+0000000003000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040404
+0404040404000404000000000000000000000000000000000000000000000000000000000303
+0303030303030303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0003000000000300000300000303030303030300000300000303030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040404040404040404
+0404000000000000000000000000000000000000000000000000000000000003030303030303
+0303030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000006065620100006560000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000300030000
+0303030303030303030303030303030303030303030303030300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040404040404040404040400000000
+0000000000000000000000000000000000000000000000000000030303030303030303030303
+0303000300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000646260630100006065000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000006061010100000000000063610101616300000000636101016163000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030303030303030300000003030303
+0303030303030300030303030303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040404040404040404040404000400000000000000
+0000000000000000000000000000000000000000000303030303030303030303030000030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000626000000100000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+621B6301000000000000621B63631B6200000000621B63631B62000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030000000000000000000000000000030003000300030300000003030003030003030300
+0300030303030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000400040404040404040404040000000000000000000000000000
+0000000000000000000000000000000003030303030303030303030300030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000100006301000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000001B6100000000616400001B610000000061640000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003000000
+0003000000000000000000030003030303030303030303030303030003000303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004000404040404040404040004000400000000000000000000000000000000
+0000000000000000000000030303030303030303030303030303030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000065640000010000
+6465000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000656000
+0000006065000065600000000060650000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000300000000000003000000000300000000
+0300030303030303030303030300000003030303030303000000000303000300000303030000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040404040404040404040400040000000000000000000000000000000000000000000000
+0000000000030303030303030303030303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000060621B63016364626300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000626300000000636200
+0062630000000063620000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000300000003030303030303000300000000030000030003
+0003000303030303030303000003000000000000000303000300000003000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040404
+0404040404040404040400000000000000000000000000000000000000000000000000000303
+0303030303030303030303030303030300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000636162016261630000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000010000000000000100000100000000
+0000010000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000300000003000003000303030303030300030000030003000300000003
+0300000003000003000000000303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040404040404040404
+0404040000000000000000000000000000000000000000000000000000000000030303030303
+0303030303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000010000000000000100000100000000000001000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0303030303030303000003000003000300030303030303030303030300000000030000000000
+0003000000000000000300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040404040404040404040400040400
+0000000000000000000000000000000000000000000000000000000303030303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000626300000000636200006263000000006362000000000000000000
+0000000000000001010101010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000030000
+0003000003000003000300000000030000030000000000000000030000000000000000000000
+0000000300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404040404040404040404040004000400000000
+0000000000000000000000000000000000000000000303030303030303030303030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000101010101000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001010101010101010100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000656000000000606500006560000000006065000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000030303030303030303
+0303030303000300030000030000000000000000000000000000000000000000000000030000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000404040404040404040404040400040000000000000000000000
+0000000000000000000000000000000003030303030303030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+631B610000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000100000000001B
+6100000000616400001B61000000006164000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030000000300000000000300000000
+0300030000030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040404040404040404040404000004000000000000000000000000000000
+0000000000000000000000000303030303030303030303030300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000001B1B0000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000621B63631B62
+00000000621B63631B6200000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000300000000000300000000030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0404040404040404040404040404000400000000000000000000000000000000000000000000
+0000000000000303030303030303030303030303030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000063620000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001010101010101000000636101016163000000006361
+0101616300000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000300000000000300030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000400040404
+0404040404040404040000000000000000000000000000000000000000000000000000000000
+0003030303030303030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040404040404040404
+0404040404000000000000000000000000000000000000000000000000000000030303030303
+0303030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000060620000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000101010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040004040404040404040404040404
+0404000000000000000000000000000000000000000000000000000303030303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001010100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000636062640000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003000000000000000000
+0000000000000000030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400000404040404040404040404040404040000000000
+0000000000000000000000000000000000000000000303030303030303030303030303000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010101
+0101016564000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000404040404040404040404040404000000000000000000000000
+0000000000000000000000000000000303030303030303030303030303030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040404040404040404040404040000040000000000000000000000000000
+0000000000000000000003030303030303030303030303000003000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000003030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004040404040404040404040404040004000000000000000000000000000000000000000000
+0000000000000303030303030303030303030303000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000040000040404
+0404040404040404040400000400000000000000000000000000000000000000000000000303
+0303030303030303030303030303000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010101010101010101010101000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040404040404040404
+0404040400040400000000000000000000000000000000000000000000000000000303030303
+0303030303030303030303000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000611B6300631B6100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040404040404040404040404040404
+0404000000000000000000000000000000000000000000000000000303030303030303030303
+0303000003000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000061
+6400000000001B61000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000004040404040404040404040404040000000004
+0000000000000000000000000000000000000303030303030303030303030303030303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000062630000000000
+6362000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004040404040404040404040404040400040404000000000000
+0000000000000000000000000000000300000003030303030303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001630000000000630100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404000404040404040404040404040404040400000000000000000000000000
+0000000000000000000300000003030303030303030303030303030300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000065640000000000646500000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0400040404040404040404040404040404040400000000000000000000000000000000000000
+0000000300000003030303030303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000063621B6300631B626300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001010100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000404040404
+0404040404040404040404040404000000000000000000000000000000000000000000000000
+0000000303030303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0101010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000636162016261630000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040404040404040404040404
+0404040404040404000400000000000000000000000000000000000000000000000003030303
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000404040404040404040404040404
+0404040000000400000000000000000000000000000000000000000003030303030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404040404040404040404040404040404040404
+0000000000000000000000000000000000000000000303030303030303030303030300000300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040004040404040404040404040404040404040400040000000000
+0000000000000000000000000000000000030303030303030303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000060656201000065600000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040404040404040404040404040404040004000004000000000000000000
+0000000000000000000000030303030303030303030303030300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000006462606301000060650000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040404040404040404040404040404040400000400000000000000000000000000000000
+0000000003030303030303030303030303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000006260000001000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040404
+0404040404040404040404040404040000000000000000000000000000000000000000000003
+0303030303030303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000001000063010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040404040404040404
+0404040404040404040404000000000000000000000000000000000000000003030303030303
+0303030303030303030300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000656400
+0001000064650000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040404040404040404040404040404
+0404040400000000000000000000000000000000000000000000030303030303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+000000000000000000000000000000000000000000000000000000000060621B630163646263
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040004040404040404040404040404040404040004
+0000000000040000000000000000000000000003030303030303030303030303030303030000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000006361620162616300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000004040404040404040404040404040404000400040000000400
+0000000000000000000000000000030303030303030303030303030303030303030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400040404040404040404040404040404040400000400040400000000000000
+0000000000000000030303030303030303030303030303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0000040404040404040404040404040404040404040004040004000000000000000000000000
+0000030303030303030303030303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000620000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000404040404
+0404040404040404040404040404040404040400000000000000000000000000000003030303
+0303030303030303030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000061
+6400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040004040404040404
+0404040404040404040400040400000000000000000000000000000000000003030303030303
+0303030303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000611B63000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000004040404040404040404040404040404
+0404040404000004000000000000000000000000000000030303030303030303030303030303
+0303030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001010101010101010100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400000404040404040404040404040404040404040004
+0000000000000000000000000000000003030303030303030303030303030303030303000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040404040404040404040404040404040404040404040400000000
+0000000000000000000000000003030303030303030303030303030303000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000004040000040400040404040404040404040404040404040400000000000000000000
+0000000000000003030303030303030303030303030303000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040400
+0000000404040404040404040404040404040404000400000000000000000000000000000000
+0003030303030303030303030303030303030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000404
+0004040404040404040404040400040000000000000000000000000000000000000003030303
+0303030303030303030303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000040400000404040404
+0404040404040404000404000000000004000000000000000000000303030303030303030303
+0303030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040404040404040404040404
+0404040400040000000400000000000000000000000303030303030303030303030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000003000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000004000004040404040404040404040404040000
+0400040000000000000000000000000000000303030303030303030303030300000300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000101010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400040404040404040404040404000000000400000000
+0000000000000000000000000303030303030303030303030303000300000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000003000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010101000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000630000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000303030303030300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004040404040404040404040404040400040004000000000000000000
+0000000000030303030303030303030303030303030303030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0060000001000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040404040404040404040404040400040404040000000004000000000303
+0303030303030303030303030303030303030300000000000000000000000000000000000000
+0000000000000000000000000000000000000003030303030303000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000101610163
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000300000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0404040404040404040404040404040400040404040000000400000000000000000303030303
+0303030303030300030303030000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000060610101626501630000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000404040404040404
+0404040404040404040004000400000400040000000000000000030303030303030303030303
+0303030303030303030000000000000000000000000000000000000000000000000000000000
+0000000000000000000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000163641B01016261000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000404040404040404040404040404
+0404000400040000000004000000000000000000000303030303030303030303030303030303
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0003030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000006164630100000001636461000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000004040404040404040404040404040404000400
+0404040400040004000000000000000000030303000303030303030003030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000006162010161646301000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004040404040404040404040404040404040004000404000000
+0400000000000000000000030303030303030303030303030303030303000000000000000000
+0000000000000000000000000000000000000000000000000000000000000300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000630165620101616463000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004040404040404040404040404040404040400040404040004000400000000
+0000000000000300000303030303030003030303030300030000000000030000000000000000
+0000000000000000000000000000000000000000000000000300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100006301616201000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004040404040404040404040404040404040004040000000400000000000000000000000000
+0303030303030303030303030303030303030000000000030000000000000000000000000000
+0000000000000000000000000000000303030303030300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000100
+0060000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000040004040404
+0404040404040404040404040404040404040004000400000000000000000000000000030303
+0303030303030303030303030000000300030000000000000000000000000000000000000000
+0000000000000000000000000300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000630000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000006061010100000000
+0000636101016163000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000404040404040404
+0404040404040400040404000000040000000000000000000000000303030303030303030303
+0303030303030303030303030303030000000000000000000000000000000000000000000000
+0000000000000300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000621B6301000000000000621B6363
+1B62000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400040404040404040404040404040404
+0404040404040004000400000000000000000000000000030303030303030303030303030303
+0000000300030000000000000000000000000000000000000000000000000000000000000000
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000001B61000000006164000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004040404040404040404040404040404040404040000
+0400000000000000000000000000000303030303030303030303030303030303030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000006560000000006065000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000404040404040404040404040404040404040404040004000400000000
+0000000000000000000000000303030303030303030303030303000000030003000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000006263000000006362000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000040404040404040404040404040404040400000404040400000000000000
+0000000303030303030303030303030303030303030000030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000100000000000001000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004040404040404040404040404040404040404040004040000000000000000000000000000
+0303030303030303030303030300030000030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000100000000000001000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000400040404
+0404040404040404040404040004040404000000000000000000000000000000030303030303
+0303030303030303030000030003030000000300000000000000000000000000000300000000
+0000000000000000030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000626300
+0000006362000000000000000000000000000000000101010101000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040004040404040404040404
+0404040004040400040400000000000000000000000000030303030303030303030303030303
+0303030303030003030000000300000000000000000000000000000300000000000000000000
+0000030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000101010101000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000656000000000606500
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004040404040400040004000004
+0004040404000000000000000000000000000000030303030303030303030303030303000003
+0003030000000300000000000000000000000000000300000000000000000000000003000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000100000000001B6100000000616400000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404040404040404000000040400040404000404
+0000000000000000000000030303030303030303030303030303030303030303030303030303
+0303030300000000000000000303030303030300000000000003030303030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000001000000000000621B63631B620000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040404040404040404040404040404040404040004040400040004
+0000000000000000030303030303030303040303030303040303030303000000030000000000
+0000000000000000000300000000000300000000000003000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010101010101010000006361010161630000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000004040404040404040404040404040404000404040004000400000000000000
+0000030003030303030303030403030304000303030303000000030000000000000000000000
+0000000300000000000300000000000003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0404040404040404040404040400040404040404000400040000000000000000000003000303
+0303030303030304030403000303030303000000030000000000000000000000000000030000
+0000000300000000000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010101000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000404040404
+0404040404040404040404040404040404000000040000000000000303030303030403030304
+0304040303040303030303030303000000000000000000030000000003030000030303030303
+0300000000000000000000000000000000000000000003000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001010100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000040004040404040404040404
+0404040404040404040400040004000000000000000003030303030304030303040403040400
+0303030303000300000000000000000000030000000003030000000000030000000000000000
+0000000000000000000000000000000003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000404040404040404040404040404040404
+0404040004000400000000000000000003030303030303040304040403040400030303030300
+0300000000000000000000030000000003030000000000030000000000000000000000000000
+0000000000000000000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000040404040404040404040404000404040404040404040004
+0004000000000003030303030303030303030404030304030304030303030303030303030000
+0000030303030303030303030303030000030000000000000000000000000000000000000000
+0003030303030303000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000404040404040404040404040404040404040404040404040004000000
+0000000003030000030303040304030403040300030303030300030300000000000000000003
+0000000003030003000000030000000000000300000000000000000000000000000000000300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000040004040404040404040404040404040404040404040400000400000000000000000303
+0000030304030303040303030400030303030300030300000000000000000003000000000303
+0003000000030000000000000300000000000000000000000000000000000300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000400040404
+0404040404040404040404040404040404040400040004000000000000000303000003040303
+0304030403030304030303030300030300000000000000000003000000000303000300000003
+0000000000000300000000000000000000000000000000000300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000030303030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000040404040404
+0404040404040404040404000004000000000000000000000003030303030303030303030303
+0303030303030303030303030300000000000000000000000303030303030303030303030303
+0303030300000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004040404040404040404040404
+0404040404040400040000000000000000000000000003030303030303030303030003030303
+0300030300000000000000000000000000000000000300000003000000000000030000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000004000404040404040404040404040404040404040404
+0404000404000004000000000004000003040303030304040303030304040303030003030300
+0300000300000300000000030003000303000003030000000000030000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000040404040404040404040404040404040404040404040404040400
+0000040000000400000003030403030304040403030404030303030003030300030000030000
+0300000000030003000303000003030000000000030000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000400040404040404040404040404040404040404040404000000000000040004
+0000000003030304030403030404040403030303030000030300030000030000030000000003
+0003000303000000030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000101010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0004000004040404040404040404040404040400040400000000000000000400000303030303
+0303040303030304040303030303030303030303030303030303030303030303030303030303
+0303030303030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010101000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000040004040404
+0404040404040404040404040404040404000000000000040004000000000303030403040303
+0404040403030303030000030300030000030000030000000003000300030300000003000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000004000004040404040404040404
+0404040404040404040004040000000004000000040000000303040303030404040303040403
+0303030000030300030000030000030000000003000300030300000003000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404000404040404040404040404040404040404
+0404040404040400000400000000000400040404040403040404040403040404030303030303
+0300030303030000030300030003030303030303030303030300030303000000000000000000
+0000000000000003000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000040004000404040404040404040404040404040404040404
+0000040004000000040000000404030404040404040304040403030303030303030003030303
+0000000300030000030303000303030303030300030303000000000000000000000000000000
+0003000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000400040004040404040404040404040404040404040404000400000004
+0004000000000304040404040404040404040303030303030303030003030303000000030003
+0000030303000303030303030300030303000000000000000000000000000000000300000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000004000400040400040404040404040404040404040000040000000000040000030303
+0303040403040403040404030303030303030303030303030303030303030303030303030303
+0303030303030303030303030303000000000000000000000303030303030300000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040004
+0004040404040404040404040404040404040404000400000004000400000000030404040404
+0404040404040303030303030303030003030303000000030003000003030300030303030303
+0300030303000000000000000000000000000000000300000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004000400040404040404
+0404040404040404040404040404000004000400000004000000040403040404040404030404
+0403030303030303030003030303000000030003000003030300030303030303030003030300
+0000000000000000000000000000000300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000400040004040404040404040404040404
+0404040404040404040000040000000000040004040304040304040404040304040403030303
+0303030003030303000000030003000003030300030303030303030003030300000000000000
+0000000000000000000300000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000400040404040404040404040404040404040404040404
+0404040000040404000003040404040404040304040404040304040403040303030303030303
+0303000003030003030303030303030303030303030303030300000303000000000000000000
+0000000000000000030000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000004000404040404040404040404040404040404040404040404000000
+0404000004040000040404040404040404030404040304030303030303030303030300000303
+0003030303030303030303030303030303030300000303000000000000000000000000000000
+0000030000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000040004040404040404040404040404040404040404040000040004000404040400
+0000000404040404040404040404030403030303030303030303030300000303000303030303
+0303030303030303030303030300000303000000000000000000000000000000000003000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0400040404040404040404040404040404040404000000000400000304040303030303030404
+0404040304040403040303030303030303030303030303030303030303030303030303030303
+0303030303030303030303030303000000000000000000000003030303030303000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000004000404040404
+0404040404040404040404040404040000040004000404040400000000040404040404040404
+0404030403030303030303030303030300000303000303030303030303030303030303030303
+0300000303000000000000000000000000000000000003000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000400040404040404040404040404
+0404040404040404040404000000040400000404000004040404040404040403040404030403
+0303030303030303030300000303000303030303030303030303030303030303030000030300
+0000000000000000000000000000000003000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000040004040404040404040404040404040404040404
+0404040404000004040400000304040404040404030404040404030404040304030303030303
+0303030300000303000303030303030303030303030303030303030000030300000000000000
+0000000000000000000003000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000004040004040404040404
+0404040404040404040404040404040404040404040404040404040403040404040403040404
+0403030303030303030303030303030303030303030303030303030303030303030303030303
+0300030303000000030003000303030000000300000000000000000000030000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000040400040404000404040404040404
+0404040404040404040404040404040404000404040404040404040404040404030303030303
+0303030303030303030303030303030303030303030303030303030303030303030003030300
+0000030003000303030000000300000000000000000000030000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000404040404040404040404040404040404040404
+0404040404040404040400000004040404040404040404040403030303030303030303030303
+0303030303030303030303030303030303030303030303030303030003030300000003000300
+0303030000000300000000000000000000030000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010101
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004040004040400040404040404040404040004040404040404
+0404040000000003040404040403040404040303030303030303030303030303030303030303
+0303030303030303030303030303030303030303030303030303030303030303030303030303
+0303030300000000030303030303030000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001010100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404040404040404040404040404040404040404040404040404040404040000
+0004040404040404040404040403030303030303030303030303030303030303030303030303
+0303030303030303030303030303030003030300000003000300030303000000030000000000
+0000000000030000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0400040404000404040404040404040404040404040404040404040404040400040404040404
+0404040404040404030303030303030303030303030303030303030303030303030303030303
+0303030303030303030003030300000003000300030303000000030000000000000000000003
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000404000404040404
+0404040404040404040404040404040404040404040404040404040404040304040404040304
+0404040303030303030303030303030303030303030303030303030303030303030303030303
+0303030003030300000003000300030303000000030000000000000000000003000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000606101010000000000000000000000
+0000000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000621B63010000000000000000000000000000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000040400
+0404000404040404040404040404040404040404040404040404040404040404040404040404
+0404040404040404040303040303030303040303030303030303030303030303030303030303
+0303030303030303030303030303030303000303030000030303030303000000000303030300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000100000000000000000000000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000010000000000000000000100
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000000000000000
+0000000000000000000100000000000000000100000000000000000000000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000010404000404040404
+0401040404040404040404040404040404040404040404040404040404040404040404040404
+0404030304030403030304030303030303030303030303030303030303030303030303030303
+0303030303030303030303000303030000030303030303000000000303030300000000000000
+0000000000000000000000000100000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000000000000000000000000000000000100000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000100000000000000000000000000000000000000000000000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000000000000000000000000000010000000000000000000100000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000000000000000000000000000
+0000000100000000000000000100000000000000000000000000000000000000000000000000
+0000000100000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000010004040404040404040404040404
+0404040404040404040404040404040404040404040404040404040404040404040403040303
+0304030403030303030303030303030303030303030303030303030303030303030303030303
+0303030303000303030000030303030303000000000303030300000000000000000000000000
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000000000000000000000000000000000100000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010101010101010101
+0101010101010101010101010101010101010101010101010101010101010100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000004040404040404040404040404040404040404040404040404
+0404040404040404040404040404040404040404040403040303030403040303030303030303
+0303030303030303030303030303030303030303030303030303030303030300030303000003
+0303030303000000000303030300000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000404000404040404040004040404040404040404040404040404040404040404
+0404040404040404040404040404040403030403040303030403030303030303030303030303
+0303030303030303030303030303030303030303030303030300030303000003030303030300
+0000000303030300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000004
+0400040400040404040404040404040404040404040404040404040404040404040404040404
+0404040404040404040404030304030303030304030303030303030303030303030303030303
+0303030303030303030303030303030303030300030303000003030303030300000000030303
+0300000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000101010101
+0101000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000606101010000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000606101010000000000006361010161630000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000606101
+0100000000000063610101616300000000636101016163000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000060610101000000000000636101016163000000006361010161
+6300000000636101016163000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000060610101000000000000
+6361010161630000000063610101616300000000636101016163000000000063610101616300
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000006061010100000000000063610101616300000000636101016163000000006361
+0101616300000000006361010161630000000063610101616300000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000062
+1B63010000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000621B6301000000000000621B63631B620000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000621B63010000000000
+00621B63631B6200000000621B63631B62000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000621B6301000000000000621B63631B6200000000621B63631B620000000062
+1B63631B62000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000621B6301000000000000621B63631B62
+00000000621B63631B6200000000621B63631B620000000000621B63631B6200000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+621B6301000000000000621B63631B6200000000621B63631B6200000000621B63631B620000
+000000621B63631B6200000000621B63631B6200000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000100000000001B6100000000616400000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000100000000001B6100000000
+616400001B610000000061640000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000100000000001B6100000000616400001B6100000000616400001B61000000006164
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000100000000001B6100000000616400001B6100
+000000616400001B610000000061640000001B61000000006164000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000001B6100000000616400001B6100000000616400001B610000000061640000001B610000
+0000616400001B61000000006164000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000656000000000606500000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000000000656000000000606500006560
+0000000060650000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000065600000000060650000656000000000606500006560000000006065000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000065600000000060650000656000000000606500
+0065600000000060650000006560000000006065000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000656000
+0000006065000065600000000060650000656000000000606500000065600000000060650000
+6560000000006065000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000001000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000626300000000636200000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000000000626300000000636200006263000000006362
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000006263
+0000000063620000626300000000636200006263000000006362000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001000000000062630000000063620000626300000000636200006263000000
+0063620000006263000000006362000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010000000000626300000000636200
+0062630000000063620000626300000000636200000062630000000063620000626300000000
+6362000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000001000000000001
+0000000000000100000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000010000000000010000000000000100000100000000000001000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000100000000000001
+0000010000000000000100000100000000000001000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000001000000000000010000010000000000000100000100000000000001000000
+0100000000000001000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000010000000000010000000000000100000100000000
+0000010000010000000000000100000001000000000000010000010000000000000100000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000001000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000001000000000000
+0100000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000010000000000010000000000000100000100000000000001000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000100000000000001000001000000
+0000000100000100000000000001000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000100000000
+0001000000000000010000010000000000000100000100000000000001000000010000000000
+0001000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000010000000000010000000000000100000100000000000001000001
+0000000000000100000001000000000000010000010000000000000100000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000001000000000062630000000063620000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+0000626300000000636200006263000000006362000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000006263000000006362000062630000000063620000
+6263000000006362000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000100000000006263000000
+0063620000626300000000636200006263000000006362000000626300000000636200000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000010000000000626300000000636200006263000000006362000062630000000063
+6200000062630000000063620000626300000000636200000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000100
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000001000000000065600000000060650000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000001000000000065600000
+0000606500006560000000006065000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000006560000000006065000065600000000060650000656000000000
+6065000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000100000000006560000000006065000065
+6000000000606500006560000000006065000000656000000000606500000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000001
+0000000000656000000000606500006560000000006065000065600000000060650000006560
+0000000060650000656000000000606500000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000100000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000100000000001B610000000061640000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000100000000001B610000000061640000
+1B61000000006164000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0100000000001B6100000000616400001B6100000000616400001B6100000000616400000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000100000000001B6100000000616400001B610000000061
+6400001B610000000061640000001B6100000000616400000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000100000000001B
+6100000000616400001B6100000000616400001B610000000061640000001B61000000006164
+00001B6100000000616400000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0001000000000000621B63631B62000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001000000000000621B63631B6200000000621B63631B
+6200000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+00621B63631B6200000000621B63631B6200000000621B63631B620000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000001000000000000621B63631B6200000000621B63631B6200000000621B
+63631B620000000000621B63631B620000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000001000000000000621B63631B62
+00000000621B63631B6200000000621B63631B620000000000621B63631B6200000000621B63
+631B620000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000101010101010100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000101010101010100
+0000636101016163000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000001010101010101000000636101016163000000006361010161630000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000010101010101010000006361010161
+6300000000636101016163000000006361010161630000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0101010101010100000063610101616300000000636101016163000000006361010161630000
+0000006361010161630000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000001010101010101000000636101016163000000006361
+0101616300000000636101016163000000000063610101616300000000636101016163000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000100000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000063016100000000000000000000000000000000000001000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000100000000000000000000006101630000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000100000000000000000000000000010000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000061620000000000000000000000000000000000000001000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000010000
+0000000000000000000062610000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000100000000000000000000000000010000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+6301600000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000010000000000000000
+0000000060016300000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000100000000636101621B00000001010101010000006065016264000000000100
+1B62016264000000006361620162640065600000000000636200000000000000646500000000
+01006162621B0000616201610000000001000000006361620162640000010061620100006065
+01016560000000001B6201016560000000606501626400000000006361620162640000606501
+01656000000001001B620162640000000063650162610001000000001B620101656000000065
+6400000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+010000000062640063611B0000000100000000006362640060626000000001611B6300606264
+000063621B630060610064650000000000611B00000000000000656400000000016164636365
+1B6164636365640000000100000063621B630060610000016164000000606264636364626000
+00611B630063606500006362640060626000000063621B630060610060626463636462600000
+01611B6300606264000063626463631B6101000000611B630063606500000064610000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000010000000000
+0000006362000000010000000000611B0000006065000000011B0000000060650000611B0000
+0000000000626300000063016300000000000000626300000000016400000060016400000060
+6500000001000000611B00000000000000011B00000000616400000000646100000100000000
+00000000611B0000006065000000611B00000000000061640000000064610000011B00000000
+60650000611B000000001B010000000100000000000000000063620000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000001000000001B620101010100
+000001000000000062630000006362000000016300000000636200006263000000000000001B
+610000001B610000000000000000010000000000016300000000016300000000010000000100
+0000626300000000000000016300000000626300000000636200006561630000000000006263
+0000006362000000626300000000000062630000000063620000016300000000636200006263
+0000000063010000006561630000000000000000010000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000010000006165600000000100000001000000
+0000010101010101010000000100000000000001000001000000000000000063626300006260
+0000000000000000010000000000010000000000010000000000010000000100000001000000
+0000000000010000000000010000000000000100006361016261600000000101010101010100
+0000010000000000000001000000000000010000010000000000000100000100000000000001
+0000006361016261600000000000010000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000010000006263000000630100000001000000000062630000
+0000000000000100000000000001000062630000000000000000611B00646500000000000000
+0000626300000000010000000000010000000000010000000100000062630000000000000001
+0000000000626300000000636200000000006364656100006263000000000000000062630000
+0000000062630000000063620000010000000000000100006263000000006301000000000000
+6364656100000063620000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000100000062630000001B0100000001000000000061640000000000000000
+01000000000000010000611B0000000000000000636200656400000000000000000061640000
+00000100000000000100000000000100000001000000611B0000000000000001000000000061
+64000000006461000000000000006301000061640000000000000000611B0000000000006164
+000000006461000001000000000000010000611B000000001B01000000000000000063010000
+0064610000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+000001000000616163631B610100000062640000000063626463006065000000010000000000
+0001000063621B6300606100000000651B620000000000000000000064650000000001000000
+0000010000000000010000000100000063621B63006061000001000000000060626463636462
+60000065646300631B6500006362646300606500000063621B63006061006062646363646260
+000001000000000000010000636264636364610100000065646300631B650000006564000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001000000
+6361620161000100000060620101000000606501016560000000010000000000000100000063
+61620165640000000060011B0000000000000000000063016000000001000000000001000000
+0000010000000100000000636162016564000001000000000000646501016560000000606162
+01621B0000000060650101656000000000636162016564000064650101656000000001000000
+000000010000006365016261000100000060616201621B000000600163000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000001630000000000000000000000616200000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000626100000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000631B6100
+0000000000000000000000630161000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000061016300000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000101610000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000
+
+end
+%%PageTrailer
+%%Trailer
+%%EOF
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/doc/libmicrohttpd_performance_data.png
^
|
(renamed from libmicrohttpd/doc/performance_data.png)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ac_define_dir.m4
^
|
@@ -0,0 +1,34 @@
+dnl @synopsis AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+dnl
+dnl This macro sets VARNAME to the expansion of the DIR variable,
+dnl taking care of fixing up ${prefix} and such.
+dnl
+dnl VARNAME is then offered as both an output variable and a C
+dnl preprocessor symbol.
+dnl
+dnl Example:
+dnl
+dnl AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+dnl
+dnl @category Misc
+dnl @author Stepan Kasal <kasal@ucw.cz>
+dnl @author Andreas Schwab <schwab@suse.de>
+dnl @author Guido U. Draheim <guidod@gmx.de>
+dnl @author Alexandre Oliva
+dnl @version 2006-10-13
+dnl @license AllPermissive
+
+AC_DEFUN([AC_DEFINE_DIR], [
+ prefix_NONE=
+ exec_prefix_NONE=
+ test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}. Thus we have to use `eval' twice.
+ eval ac_define_dir="\"[$]$2\""
+ eval ac_define_dir="\"$ac_define_dir\""
+ AC_SUBST($1, "$ac_define_dir")
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3])
+ test "$prefix_NONE" && prefix=NONE
+ test "$exec_prefix_NONE" && exec_prefix=NONE
+])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_append_compile_flags.m4
^
|
@@ -30,33 +30,12 @@
#
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 6
+#serial 7
AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_append_flag.m4
^
|
@@ -23,33 +23,12 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 7
+#serial 8
AC_DEFUN([AX_APPEND_FLAG],
[dnl
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_append_link_flags.m4
^
|
@@ -1,5 +1,5 @@
# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
+# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
# ===========================================================================
#
# SYNOPSIS
@@ -28,33 +28,12 @@
#
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 5
+#serial 7
AC_DEFUN([AX_APPEND_LINK_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_check_compile_flag.m4
^
|
@@ -29,33 +29,12 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 5
+#serial 6
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_check_link_flag.m4
^
|
@@ -29,33 +29,12 @@
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
-#serial 5
+#serial 6
AC_DEFUN([AX_CHECK_LINK_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_have_epoll.m4
^
|
@@ -42,11 +42,11 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 11
+#serial 12
AC_DEFUN([AX_HAVE_EPOLL], [dnl
ax_have_epoll_cppflags="${CPPFLAGS}"
- AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"])
+ AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"], [], [AC_INCLUDES_DEFAULT])
AC_MSG_CHECKING([for Linux epoll(7) interface])
AC_CACHE_VAL([ax_cv_have_epoll], [dnl
AC_LINK_IFELSE([dnl
@@ -59,10 +59,10 @@
# endif
#endif
], [dnl
-int fd, rc;
+int fd;
struct epoll_event ev;
fd = epoll_create(128);
-rc = epoll_wait(fd, &ev, 1, 0);])],
+epoll_wait(fd, &ev, 1, 0);])],
[ax_cv_have_epoll=yes],
[ax_cv_have_epoll=no])])
CPPFLAGS="${ax_have_epoll_cppflags}"
@@ -89,11 +89,11 @@
#include <sys/epoll.h>
#include <signal.h>
], [dnl
-int fd, rc;
+int fd;
struct epoll_event ev;
fd = epoll_create(128);
-rc = epoll_wait(fd, &ev, 1, 0);
-rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])],
+epoll_wait(fd, &ev, 1, 0);
+epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])],
[ax_cv_have_epoll_pwait=yes],
[ax_cv_have_epoll_pwait=no])])
CPPFLAGS="${ax_have_epoll_cppflags}"
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/ax_pthread.m4
^
|
@@ -55,6 +55,7 @@
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -82,7 +83,8 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
-#serial 24
+# locally patched for autoconf 2.70 compatibility
+#serial 27
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
@@ -123,10 +125,12 @@
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
@@ -194,14 +198,47 @@
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
- ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
;;
esac
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+ [ax_cv_PTHREAD_CLANG],
+ [ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+ ],
+ [ax_cv_PTHREAD_CLANG=yes])
+ fi
+ ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
AS_IF([test "x$GCC" = "xyes"],
- [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
+ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+AS_IF([test "x$ax_pthread_clang" = "xyes"],
+ [ax_pthread_flags="-pthread,-lpthread -pthread"])
+
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
@@ -224,25 +261,86 @@
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
-# Are we compiling with Clang?
-AC_CACHE_CHECK([whether $CC is Clang],
- [ax_cv_PTHREAD_CLANG],
- [ax_cv_PTHREAD_CLANG=no
- # Note that Autoconf sets GCC=yes for Clang as well as GCC
- if test "x$GCC" = "xyes"; then
- AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
- [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
-# if defined(__clang__) && defined(__llvm__)
- AX_PTHREAD_CC_IS_CLANG
-# endif
- ],
- [ax_cv_PTHREAD_CLANG=yes])
- fi
- ])
-ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ *,*)
+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
+ ;;
+ esac
+
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void *some_global = NULL;
+ static void routine(void *a)
+ {
+ /* To avoid any unused-parameter or
+ unused-but-set-parameter warning. */
+ some_global = a;
+ }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
-ax_pthread_clang_warning=no
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
@@ -261,11 +359,6 @@
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
- PTHREAD_CFLAGS="-pthread"
- PTHREAD_LIBS=
-
- ax_pthread_ok=yes
-
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
@@ -294,7 +387,7 @@
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
- ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
@@ -320,78 +413,7 @@
fi # $ax_pthread_clang = yes
-if test "x$ax_pthread_ok" = "xno"; then
-for ax_pthread_try_flag in $ax_pthread_flags; do
-
- case $ax_pthread_try_flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -mt,pthread)
- AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
- PTHREAD_CFLAGS="-mt"
- PTHREAD_LIBS="-lpthread"
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
- PTHREAD_CFLAGS="$ax_pthread_try_flag"
- ;;
-
- pthread-config)
- AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
- AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
- *)
- AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
- PTHREAD_LIBS="-l$ax_pthread_try_flag"
- ;;
- esac
-
- ax_pthread_save_CFLAGS="$CFLAGS"
- ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
-
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-# if $ax_pthread_check_cond
-# error "$ax_pthread_check_macro must be defined"
-# endif
- static void routine(void *a) { a = 0; }
- static void *start_routine(void *a) { return a; }],
- [pthread_t th; pthread_attr_t attr;
- pthread_create(&th, 0, start_routine, 0);
- pthread_join(th, 0);
- pthread_attr_init(&attr);
- pthread_cleanup_push(routine, 0);
- pthread_cleanup_pop(0) /* ; */])],
- [ax_pthread_ok=yes],
- [])
-
- CFLAGS="$ax_pthread_save_CFLAGS"
- LIBS="$ax_pthread_save_LIBS"
-
- AC_MSG_RESULT([$ax_pthread_ok])
- AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
# Various other checks:
if test "x$ax_pthread_ok" = "xyes"; then
@@ -438,7 +460,8 @@
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
- [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [[int i = PTHREAD_PRIO_INHERIT;
+ return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/extern-inline.m4
^
|
@@ -1,6 +1,6 @@
dnl 'extern inline' a la ISO C99.
-dnl Copyright 2012-2016 Free Software Foundation, Inc.
+dnl Copyright 2012-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
[/* Please see the Gnulib manual for how to use these macros.
Suppress extern inline with HP-UX cc, as it appears to be broken; see
- <http://lists.gnu.org/archive/html/bug-texinfo/2013-02/msg00030.html>.
+ <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
Suppress extern inline with Sun C in standards-conformance mode, as it
mishandles inline functions that call each other. E.g., for 'inline void f
@@ -25,20 +25,32 @@
if isdigit is mistakenly implemented via a static inline function,
a program containing an extern inline function that calls isdigit
may not work since the C standard prohibits extern inline functions
- from calling static functions. This bug is known to occur on:
+ from calling static functions (ISO C 99 section 6.7.4.(3).
+ This bug is known to occur on:
OS X 10.8 and earlier; see:
- http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html
+ https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
DragonFly; see
- http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log
+ http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log
FreeBSD; see:
- http://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00104.html
+ https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
- for clang but remains for g++; see <http://trac.macports.org/ticket/41033>.
- Assume DragonFly and FreeBSD will be similar. */
+ for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
+ Assume DragonFly and FreeBSD will be similar.
+
+ GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+ inline semantics, unless -fgnu89-inline is used. It defines a macro
+ __GNUC_STDC_INLINE__ to indicate this situation or a macro
+ __GNUC_GNU_INLINE__ to indicate the opposite situation.
+ GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
+ semantics but warns, unless -fgnu89-inline is used:
+ warning: C99 inline functions are not supported; using GNU89
+ warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
+ It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
+ */
#if (((defined __APPLE__ && defined __MACH__) \
|| defined __DragonFly__ || defined __FreeBSD__) \
&& (defined __header_inline \
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/fcntl-o.m4
^
|
@@ -1,23 +1,22 @@
-# fcntl-o.m4 serial 4
-dnl Copyright (C) 2006, 2009-2016 Free Software Foundation, Inc.
+# fcntl-o.m4 serial 7
+dnl Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Written by Paul Eggert.
+AC_PREREQ([2.60])
+
# Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
AC_DEFUN([gl_FCNTL_O_FLAGS],
[
dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
- dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
- dnl AC_GNU_SOURCE.
- m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
- [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
- [AC_REQUIRE([AC_GNU_SOURCE])])
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CHECK_HEADERS_ONCE([unistd.h])
AC_CHECK_FUNCS_ONCE([symlink])
AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
@@ -33,6 +32,7 @@
# defined sleep(n) _sleep ((n) * 1000)
#endif
#include <fcntl.h>
+ ]GL_MDA_DEFINES[
#ifndef O_NOATIME
#define O_NOATIME 0
#endif
@@ -116,7 +116,13 @@
68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
*) gl_cv_header_working_fcntl_h='no';;
esac],
- [gl_cv_header_working_fcntl_h=cross-compiling])])
+ [case "$host_os" in
+ # Guess 'no' on native Windows.
+ mingw*) gl_cv_header_working_fcntl_h='no' ;;
+ *) gl_cv_header_working_fcntl_h=cross-compiling ;;
+ esac
+ ])
+ ])
case $gl_cv_header_working_fcntl_h in #(
*O_NOATIME* | no | cross-compiling) ac_val=0;; #(
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/gettext.m4
^
|
@@ -1,15 +1,15 @@
-# gettext.m4 serial 68 (gettext-0.19.8)
-dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
+# gettext.m4 serial 71 (gettext-0.20.2)
+dnl Copyright (C) 1995-2014, 2016, 2018-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
@@ -20,15 +20,13 @@
dnl Macro to add for using GNU gettext.
dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
-dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
-dnl default (if it is not specified or empty) is 'no-libtool'.
-dnl INTLSYMBOL should be 'external' for packages with no intl directory,
-dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl INTLSYMBOL must be one of 'external', 'use-libtool'.
+dnl INTLSYMBOL should be 'external' for packages other than GNU gettext, and
+dnl 'use-libtool' for the packages 'gettext-runtime' and 'gettext-tools'.
dnl If INTLSYMBOL is 'use-libtool', then a libtool library
dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
dnl depending on --{enable,disable}-{shared,static} and on the presence of
-dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
-dnl $(top_builddir)/intl/libintl.a will be created.
+dnl AM-DISABLE-SHARED).
dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
dnl implementations (in libc or libintl) without the ngettext() function
dnl will be ignored. If NEEDSYMBOL is specified and is
@@ -57,19 +55,17 @@
AC_DEFUN([AM_GNU_GETTEXT],
[
dnl Argument checking.
- ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [use-libtool], ,
[errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
-])])])])])
+])])])])
ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
- [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
+ [errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported.
+])])
ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
[errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
])])])])
define([gt_included_intl],
- ifelse([$1], [external],
- ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
- [yes]))
- define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+ ifelse([$1], [external], [no], [yes]))
gt_NEEDS_INIT
AM_GNU_GETTEXT_NEED([$2])
@@ -91,8 +87,7 @@
dnl again, outside any 'if'. There are two solutions:
dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
- dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
- dnl documented, we avoid it.
+ dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it.
ifelse(gt_included_intl, yes, , [
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
])
@@ -278,8 +273,8 @@
dnl Mark actions used to generate GNU NLS library.
BUILD_INCLUDED_LIBINTL=yes
USE_INCLUDED_LIBINTL=yes
- LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
- LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+ LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD"
+ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD"
LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
fi
@@ -347,43 +342,14 @@
fi
ifelse(gt_included_intl, yes, [
- dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
- dnl to 'yes' because some of the testsuite requires it.
- if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
- BUILD_INCLUDED_LIBINTL=yes
- fi
+ dnl In GNU gettext we have to set BUILD_INCLUDED_LIBINTL to 'yes'
+ dnl because some of the testsuite requires it.
+ BUILD_INCLUDED_LIBINTL=yes
dnl Make all variables we use known to autoconf.
AC_SUBST([BUILD_INCLUDED_LIBINTL])
AC_SUBST([USE_INCLUDED_LIBINTL])
AC_SUBST([CATOBJEXT])
-
- dnl For backward compatibility. Some configure.ins may be using this.
- nls_cv_header_intl=
- nls_cv_header_libgt=
-
- dnl For backward compatibility. Some Makefiles may be using this.
- DATADIRNAME=share
- AC_SUBST([DATADIRNAME])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INSTOBJEXT=.mo
- AC_SUBST([INSTOBJEXT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- GENCAT=gencat
- AC_SUBST([GENCAT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INTLOBJS=
- if test "$USE_INCLUDED_LIBINTL" = yes; then
- INTLOBJS="\$(GETTOBJS)"
- fi
- AC_SUBST([INTLOBJS])
-
- dnl Enable libtool support if the surrounding package wishes it.
- INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
- AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
])
dnl For backward compatibility. Some Makefiles may be using this.
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/host-cpu-c-abi.m4
^
|
@@ -0,0 +1,675 @@
+# host-cpu-c-abi.m4 serial 13
+dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible and Sam Steingold.
+
+dnl Sets the HOST_CPU variable to the canonical name of the CPU.
+dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its
+dnl C language ABI (application binary interface).
+dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in
+dnl config.h.
+dnl
+dnl This canonical name can be used to select a particular assembly language
+dnl source file that will interoperate with C code on the given host.
+dnl
+dnl For example:
+dnl * 'i386' and 'sparc' are different canonical names, because code for i386
+dnl will not run on SPARC CPUs and vice versa. They have different
+dnl instruction sets.
+dnl * 'sparc' and 'sparc64' are different canonical names, because code for
+dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code
+dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit
+dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit
+dnl mode, but not both.
+dnl * 'mips' and 'mipsn32' are different canonical names, because they use
+dnl different argument passing and return conventions for C functions, and
+dnl although the instruction set of 'mips' is a large subset of the
+dnl instruction set of 'mipsn32'.
+dnl * 'mipsn32' and 'mips64' are different canonical names, because they use
+dnl different sizes for the C types like 'int' and 'void *', and although
+dnl the instruction sets of 'mipsn32' and 'mips64' are the same.
+dnl * The same canonical name is used for different endiannesses. You can
+dnl determine the endianness through preprocessor symbols:
+dnl - 'arm': test __ARMEL__.
+dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL.
+dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN.
+dnl * The same name 'i386' is used for CPUs of type i386, i486, i586
+dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because
+dnl - Instructions that do not exist on all of these CPUs (cmpxchg,
+dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your
+dnl assembly language source files use such instructions, you will
+dnl need to make the distinction.
+dnl - Speed of execution of the common instruction set is reasonable across
+dnl the entire family of CPUs. If you have assembly language source files
+dnl that are optimized for particular CPU types (like GNU gmp has), you
+dnl will need to make the distinction.
+dnl See <https://en.wikipedia.org/wiki/X86_instruction_listings>.
+AC_DEFUN([gl_HOST_CPU_C_ABI],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([gl_C_ASM])
+ AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi],
+ [case "$host_cpu" in
+
+changequote(,)dnl
+ i[34567]86 )
+changequote([,])dnl
+ gl_cv_host_cpu_c_abi=i386
+ ;;
+
+ x86_64 )
+ # On x86_64 systems, the C compiler may be generating code in one of
+ # these ABIs:
+ # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
+ # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
+ # with native Windows (mingw, MSVC).
+ # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
+ # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if (defined __x86_64__ || defined __amd64__ \
+ || defined _M_X64 || defined _M_AMD64)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __ILP32__ || defined _ILP32
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=x86_64-x32],
+ [gl_cv_host_cpu_c_abi=x86_64])],
+ [gl_cv_host_cpu_c_abi=i386])
+ ;;
+
+changequote(,)dnl
+ alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
+changequote([,])dnl
+ gl_cv_host_cpu_c_abi=alpha
+ ;;
+
+ arm* | aarch64 )
+ # Assume arm with EABI.
+ # On arm64 systems, the C compiler may be generating code in one of
+ # these ABIs:
+ # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
+ # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
+ # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef __aarch64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __ILP32__ || defined _ILP32
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=arm64-ilp32],
+ [gl_cv_host_cpu_c_abi=arm64])],
+ [# Don't distinguish little-endian and big-endian arm, since they
+ # don't require different machine code for simple operations and
+ # since the user can distinguish them through the preprocessor
+ # defines __ARMEL__ vs. __ARMEB__.
+ # But distinguish arm which passes floating-point arguments and
+ # return values in integer registers (r0, r1, ...) - this is
+ # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which
+ # passes them in float registers (s0, s1, ...) and double registers
+ # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer
+ # sets the preprocessor defines __ARM_PCS (for the first case) and
+ # __ARM_PCS_VFP (for the second case), but older GCC does not.
+ echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c
+ # Look for a reference to the register d0 in the .s file.
+ AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1
+ if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then
+ gl_cv_host_cpu_c_abi=armhf
+ else
+ gl_cv_host_cpu_c_abi=arm
+ fi
+ rm -f conftest*
+ ])
+ ;;
+
+ hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
+ # On hppa, the C compiler may be generating 32-bit code or 64-bit
+ # code. In the latter case, it defines _LP64 and __LP64__.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef __LP64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=hppa64],
+ [gl_cv_host_cpu_c_abi=hppa])
+ ;;
+
+ ia64* )
+ # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
+ # 32-bit code. In the latter case, it defines _ILP32.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef _ILP32
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=ia64-ilp32],
+ [gl_cv_host_cpu_c_abi=ia64])
+ ;;
+
+ mips* )
+ # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
+ # at 32.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=mips64],
+ [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but
+ # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.
+ # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but
+ # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if (_MIPS_SIM == _ABIN32)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=mipsn32],
+ [gl_cv_host_cpu_c_abi=mips])])
+ ;;
+
+ powerpc* )
+ # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
+ # No need to distinguish them here; the caller may distinguish
+ # them based on the OS.
+ # On powerpc64 systems, the C compiler may still be generating
+ # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
+ # be generating 64-bit code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __powerpc64__ || defined _ARCH_PPC64
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [# On powerpc64, there are two ABIs on Linux: The AIX compatible
+ # one and the ELFv2 one. The latter defines _CALL_ELF=2.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined _CALL_ELF && _CALL_ELF == 2
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=powerpc64-elfv2],
+ [gl_cv_host_cpu_c_abi=powerpc64])
+ ],
+ [gl_cv_host_cpu_c_abi=powerpc])
+ ;;
+
+ rs6000 )
+ gl_cv_host_cpu_c_abi=powerpc
+ ;;
+
+ riscv32 | riscv64 )
+ # There are 2 architectures (with variants): rv32* and rv64*.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if __riscv_xlen == 64
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [cpu=riscv64],
+ [cpu=riscv32])
+ # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
+ # Size of 'long' and 'void *':
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __LP64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [main_abi=lp64],
+ [main_abi=ilp32])
+ # Float ABIs:
+ # __riscv_float_abi_double:
+ # 'float' and 'double' are passed in floating-point registers.
+ # __riscv_float_abi_single:
+ # 'float' are passed in floating-point registers.
+ # __riscv_float_abi_soft:
+ # No values are passed in floating-point registers.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __riscv_float_abi_double
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [float_abi=d],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __riscv_float_abi_single
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [float_abi=f],
+ [float_abi=''])
+ ])
+ gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}"
+ ;;
+
+ s390* )
+ # On s390x, the C compiler may be generating 64-bit (= s390x) code
+ # or 31-bit (= s390) code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __LP64__ || defined __s390x__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=s390x],
+ [gl_cv_host_cpu_c_abi=s390])
+ ;;
+
+ sparc | sparc64 )
+ # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
+ # C compiler still generates 32-bit code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __sparcv9 || defined __arch64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi=sparc64],
+ [gl_cv_host_cpu_c_abi=sparc])
+ ;;
+
+ *)
+ gl_cv_host_cpu_c_abi="$host_cpu"
+ ;;
+ esac
+ ])
+
+ dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
+ HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
+ HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
+ AC_SUBST([HOST_CPU])
+ AC_SUBST([HOST_CPU_C_ABI])
+
+ # This was
+ # AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
+ # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
+ # earlier, but KAI C++ 3.2d doesn't like this.
+ sed -e 's/-/_/g' >> confdefs.h <<EOF
+#ifndef __${HOST_CPU}__
+#define __${HOST_CPU}__ 1
+#endif
+#ifndef __${HOST_CPU_C_ABI}__
+#define __${HOST_CPU_C_ABI}__ 1
+#endif
+EOF
+ AH_TOP([/* CPU and C ABI indicator */
+#ifndef __i386__
+#undef __i386__
+#endif
+#ifndef __x86_64_x32__
+#undef __x86_64_x32__
+#endif
+#ifndef __x86_64__
+#undef __x86_64__
+#endif
+#ifndef __alpha__
+#undef __alpha__
+#endif
+#ifndef __arm__
+#undef __arm__
+#endif
+#ifndef __armhf__
+#undef __armhf__
+#endif
+#ifndef __arm64_ilp32__
+#undef __arm64_ilp32__
+#endif
+#ifndef __arm64__
+#undef __arm64__
+#endif
+#ifndef __hppa__
+#undef __hppa__
+#endif
+#ifndef __hppa64__
+#undef __hppa64__
+#endif
+#ifndef __ia64_ilp32__
+#undef __ia64_ilp32__
+#endif
+#ifndef __ia64__
+#undef __ia64__
+#endif
+#ifndef __m68k__
+#undef __m68k__
+#endif
+#ifndef __mips__
+#undef __mips__
+#endif
+#ifndef __mipsn32__
+#undef __mipsn32__
+#endif
+#ifndef __mips64__
+#undef __mips64__
+#endif
+#ifndef __powerpc__
+#undef __powerpc__
+#endif
+#ifndef __powerpc64__
+#undef __powerpc64__
+#endif
+#ifndef __powerpc64_elfv2__
+#undef __powerpc64_elfv2__
+#endif
+#ifndef __riscv32__
+#undef __riscv32__
+#endif
+#ifndef __riscv64__
+#undef __riscv64__
+#endif
+#ifndef __riscv32_ilp32__
+#undef __riscv32_ilp32__
+#endif
+#ifndef __riscv32_ilp32f__
+#undef __riscv32_ilp32f__
+#endif
+#ifndef __riscv32_ilp32d__
+#undef __riscv32_ilp32d__
+#endif
+#ifndef __riscv64_ilp32__
+#undef __riscv64_ilp32__
+#endif
+#ifndef __riscv64_ilp32f__
+#undef __riscv64_ilp32f__
+#endif
+#ifndef __riscv64_ilp32d__
+#undef __riscv64_ilp32d__
+#endif
+#ifndef __riscv64_lp64__
+#undef __riscv64_lp64__
+#endif
+#ifndef __riscv64_lp64f__
+#undef __riscv64_lp64f__
+#endif
+#ifndef __riscv64_lp64d__
+#undef __riscv64_lp64d__
+#endif
+#ifndef __s390__
+#undef __s390__
+#endif
+#ifndef __s390x__
+#undef __s390x__
+#endif
+#ifndef __sh__
+#undef __sh__
+#endif
+#ifndef __sparc__
+#undef __sparc__
+#endif
+#ifndef __sparc64__
+#undef __sparc64__
+#endif
+])
+
+])
+
+
+dnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI
+dnl (application binary interface) is a 32-bit one, to 'no' if it is a 64-bit
+dnl one, or to 'unknown' if unknown.
+dnl This is a simplified variant of gl_HOST_CPU_C_ABI.
+AC_DEFUN([gl_HOST_CPU_C_ABI_32BIT],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit],
+ [if test -n "$gl_cv_host_cpu_c_abi"; then
+ case "$gl_cv_host_cpu_c_abi" in
+ i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)
+ gl_cv_host_cpu_c_abi_32bit=yes ;;
+ x86_64 | alpha | arm64 | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 )
+ gl_cv_host_cpu_c_abi_32bit=no ;;
+ *)
+ gl_cv_host_cpu_c_abi_32bit=unknown ;;
+ esac
+ else
+ case "$host_cpu" in
+
+ # CPUs that only support a 32-bit ABI.
+ arc \
+ | bfin \
+ | cris* \
+ | csky \
+ | epiphany \
+ | ft32 \
+ | h8300 \
+ | m68k \
+ | microblaze | microblazeel \
+ | nds32 | nds32le | nds32be \
+ | nios2 | nios2eb | nios2el \
+ | or1k* \
+ | or32 \
+ | sh | sh[1234] | sh[1234]e[lb] \
+ | tic6x \
+ | xtensa* )
+ gl_cv_host_cpu_c_abi_32bit=yes
+ ;;
+
+ # CPUs that only support a 64-bit ABI.
+changequote(,)dnl
+ alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \
+ | mmix )
+changequote([,])dnl
+ gl_cv_host_cpu_c_abi_32bit=no
+ ;;
+
+changequote(,)dnl
+ i[34567]86 )
+changequote([,])dnl
+ gl_cv_host_cpu_c_abi_32bit=yes
+ ;;
+
+ x86_64 )
+ # On x86_64 systems, the C compiler may be generating code in one of
+ # these ABIs:
+ # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
+ # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
+ # with native Windows (mingw, MSVC).
+ # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
+ # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if (defined __x86_64__ || defined __amd64__ \
+ || defined _M_X64 || defined _M_AMD64) \
+ && !(defined __ILP32__ || defined _ILP32)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ arm* | aarch64 )
+ # Assume arm with EABI.
+ # On arm64 systems, the C compiler may be generating code in one of
+ # these ABIs:
+ # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
+ # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
+ # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
+ # On hppa, the C compiler may be generating 32-bit code or 64-bit
+ # code. In the latter case, it defines _LP64 and __LP64__.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef __LP64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ ia64* )
+ # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
+ # 32-bit code. In the latter case, it defines _ILP32.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifdef _ILP32
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=yes],
+ [gl_cv_host_cpu_c_abi_32bit=no])
+ ;;
+
+ mips* )
+ # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
+ # at 32.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ powerpc* )
+ # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
+ # No need to distinguish them here; the caller may distinguish
+ # them based on the OS.
+ # On powerpc64 systems, the C compiler may still be generating
+ # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
+ # be generating 64-bit code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __powerpc64__ || defined _ARCH_PPC64
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ rs6000 )
+ gl_cv_host_cpu_c_abi_32bit=yes
+ ;;
+
+ riscv32 | riscv64 )
+ # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
+ # Size of 'long' and 'void *':
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __LP64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ s390* )
+ # On s390x, the C compiler may be generating 64-bit (= s390x) code
+ # or 31-bit (= s390) code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __LP64__ || defined __s390x__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ sparc | sparc64 )
+ # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
+ # C compiler still generates 32-bit code.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __sparcv9 || defined __arch64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [gl_cv_host_cpu_c_abi_32bit=no],
+ [gl_cv_host_cpu_c_abi_32bit=yes])
+ ;;
+
+ *)
+ gl_cv_host_cpu_c_abi_32bit=unknown
+ ;;
+ esac
+ fi
+ ])
+
+ HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit"
+])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/iconv.m4
^
|
@@ -1,11 +1,18 @@
-# iconv.m4 serial 20
-dnl Copyright (C) 2000-2002, 2007-2014, 2016 Free Software Foundation, Inc.
+# iconv.m4 serial 24
+dnl Copyright (C) 2000-2002, 2007-2014, 2016-2021 Free Software Foundation,
+dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
+AC_PREREQ([2.64])
+
+dnl Note: AM_ICONV is documented in the GNU gettext manual
+dnl <https://www.gnu.org/software/gettext/manual/html_node/AM_005fICONV.html>.
+dnl Don't make changes that are incompatible with that documentation!
+
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
[
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
@@ -85,8 +92,9 @@
#endif
]],
[[int result = 0;
- /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
- returns. */
+ /* Test against AIX 5.1...7.2 bug: Failures are not distinguishable from
+ successful returns. This is even documented in
+ <https://www.ibm.com/support/knowledgecenter/ssw_aix_72/i_bostechref/iconv.html> */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
@@ -167,15 +175,27 @@
#endif
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
provided. */
- if (/* Try standardized names. */
- iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
- /* Try IRIX, OSF/1 names. */
- && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
- /* Try AIX names. */
- && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
- /* Try HP-UX names. */
- && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
- result |= 16;
+ {
+ /* Try standardized names. */
+ iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP");
+ /* Try IRIX, OSF/1 names. */
+ iconv_t cd2 = iconv_open ("UTF-8", "eucJP");
+ /* Try AIX names. */
+ iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP");
+ /* Try HP-UX names. */
+ iconv_t cd4 = iconv_open ("utf8", "eucJP");
+ if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1)
+ && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1))
+ result |= 16;
+ if (cd1 != (iconv_t)(-1))
+ iconv_close (cd1);
+ if (cd2 != (iconv_t)(-1))
+ iconv_close (cd2);
+ if (cd3 != (iconv_t)(-1))
+ iconv_close (cd3);
+ if (cd4 != (iconv_t)(-1))
+ iconv_close (cd4);
+ }
return result;
]])],
[am_cv_func_iconv_works=yes], ,
@@ -212,8 +232,7 @@
AC_SUBST([LTLIBICONV])
])
-dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
-dnl avoid warnings like
+dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
dnl This is tricky because of the way 'aclocal' is implemented:
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
@@ -221,54 +240,43 @@
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
dnl warnings.
-m4_define([gl_iconv_AC_DEFUN],
- m4_version_prereq([2.64],
- [[AC_DEFUN_ONCE(
- [$1], [$2])]],
- [m4_ifdef([gl_00GNULIB],
- [[AC_DEFUN_ONCE(
- [$1], [$2])]],
- [[AC_DEFUN(
- [$1], [$2])]])]))
-gl_iconv_AC_DEFUN([AM_ICONV],
+AC_DEFUN_ONCE([AM_ICONV],
[
AM_ICONV_LINK
if test "$am_cv_func_iconv" = yes; then
- AC_MSG_CHECKING([for iconv declaration])
- AC_CACHE_VAL([am_cv_proto_iconv], [
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [[
+ AC_CACHE_CHECK([whether iconv is compatible with its POSIX signature],
+ [gl_cv_iconv_nonconst],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
-#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
- ]],
- [[]])],
- [am_cv_proto_iconv_arg1=""],
- [am_cv_proto_iconv_arg1="const"])
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
- am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
- AC_MSG_RESULT([
- $am_cv_proto_iconv])
+ ]],
+ [[]])],
+ [gl_cv_iconv_nonconst=yes],
+ [gl_cv_iconv_nonconst=no])
+ ])
else
dnl When compiling GNU libiconv on a system that does not have iconv yet,
dnl pick the POSIX compliant declaration without 'const'.
- am_cv_proto_iconv_arg1=""
+ gl_cv_iconv_nonconst=yes
+ fi
+ if test $gl_cv_iconv_nonconst = yes; then
+ iconv_arg1=""
+ else
+ iconv_arg1="const"
fi
- AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+ AC_DEFINE_UNQUOTED([ICONV_CONST], [$iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
m4_ifdef([gl_ICONV_H_DEFAULTS],
[AC_REQUIRE([gl_ICONV_H_DEFAULTS])
- if test -n "$am_cv_proto_iconv_arg1"; then
+ if test $gl_cv_iconv_nonconst != yes; then
ICONV_CONST="const"
fi
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/intdiv0.m4
^
|
@@ -1,5 +1,5 @@
-# intdiv0.m4 serial 6 (gettext-0.18.2)
-dnl Copyright (C) 2002, 2007-2008, 2010-2016 Free Software Foundation, Inc.
+# intdiv0.m4 serial 7 (gettext-0.20.2)
+dnl Copyright (C) 2002, 2007-2008, 2010-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -31,8 +31,11 @@
if test -z "$gt_cv_int_divbyzero_sigfpe"; then
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
-#include <stdlib.h>
+#include <stdlib.h> /* for exit() */
#include <signal.h>
+#if !(defined _WIN32 && !defined __CYGWIN__)
+#include <unistd.h> /* for _exit() */
+#endif
static void
sigfpe_handler (int sig)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/intl-thread-locale.m4
^
|
@@ -0,0 +1,219 @@
+# intl-thread-locale.m4 serial 9
+dnl Copyright (C) 2015-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Lesser General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Lesser General Public License, and the rest of the GNU
+dnl gettext package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Check how to retrieve the name of a per-thread locale (POSIX locale_t).
+dnl Sets gt_nameless_locales.
+AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ dnl Persuade Solaris <locale.h> to define 'locale_t'.
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ dnl Test whether uselocale() exists and works at all.
+ gt_FUNC_USELOCALE
+
+ dnl On OpenBSD >= 6.2, the locale_t type and the uselocale(), newlocale(),
+ dnl duplocale(), freelocale() functions exist but are effectively useless,
+ dnl because the locale_t value depends only on the LC_CTYPE category of the
+ dnl locale and furthermore contains only one bit of information (it
+ dnl distinguishes the "C" locale from the *.UTF-8 locales). See
+ dnl <https://cvsweb.openbsd.org/src/lib/libc/locale/newlocale.c?rev=1.1&content-type=text/x-cvsweb-markup>.
+ dnl In the setlocale() implementation they have thought about the programs
+ dnl that use the API ("Even though only LC_CTYPE has any effect in the
+ dnl OpenBSD base system, store complete information about the global locale,
+ dnl such that third-party software can access it"), but for uselocale()
+ dnl they did not think about the programs.
+ dnl In this situation, even the HAVE_NAMELESS_LOCALES support does not work.
+ dnl So, define HAVE_FAKE_LOCALES and disable all locale_t support.
+ case "$gt_cv_func_uselocale_works" in
+ *yes)
+ AC_CHECK_HEADERS_ONCE([xlocale.h])
+ AC_CACHE_CHECK([for fake locale system (OpenBSD)],
+ [gt_cv_locale_fake],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <locale.h>
+#if HAVE_XLOCALE_H
+# include <xlocale.h>
+#endif
+int main ()
+{
+ locale_t loc1, loc2;
+ if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) return 1;
+ if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL) return 1;
+ loc1 = newlocale (LC_ALL_MASK, "de_DE.UTF-8", (locale_t)0);
+ loc2 = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", (locale_t)0);
+ return !(loc1 == loc2);
+}]])],
+ [gt_cv_locale_fake=yes],
+ [gt_cv_locale_fake=no],
+ [dnl Guess the locale system is fake only on OpenBSD.
+ case "$host_os" in
+ openbsd*) gt_cv_locale_fake="guessing yes" ;;
+ *) gt_cv_locale_fake="guessing no" ;;
+ esac
+ ])
+ ])
+ ;;
+ *) gt_cv_locale_fake=no ;;
+ esac
+ case "$gt_cv_locale_fake" in
+ *yes)
+ gt_fake_locales=yes
+ AC_DEFINE([HAVE_FAKE_LOCALES], [1],
+ [Define if the locale_t type contains insufficient information, as on OpenBSD.])
+ ;;
+ *)
+ gt_fake_locales=no
+ ;;
+ esac
+
+ case "$gt_cv_func_uselocale_works" in
+ *yes)
+ AC_CACHE_CHECK([for Solaris 11.4 locale system],
+ [gt_cv_locale_solaris114],
+ [case "$host_os" in
+ solaris*)
+ dnl Test whether <locale.h> defines locale_t as a typedef of
+ dnl 'struct _LC_locale_t **' (whereas Illumos defines it as a
+ dnl typedef of 'struct _locale *').
+ dnl Another possible test would be to include <sys/localedef.h>
+ dnl and test whether it defines the _LC_core_data_locale_t type.
+ dnl This type was added in Solaris 11.4.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <locale.h>
+ struct _LC_locale_t *x;
+ locale_t y;
+ ]],
+ [[*y = x;]])],
+ [gt_cv_locale_solaris114=yes],
+ [gt_cv_locale_solaris114=no])
+ ;;
+ *) gt_cv_locale_solaris114=no ;;
+ esac
+ ])
+ ;;
+ *) gt_cv_locale_solaris114=no ;;
+ esac
+ if test $gt_cv_locale_solaris114 = yes; then
+ AC_DEFINE([HAVE_SOLARIS114_LOCALES], [1],
+ [Define if the locale_t type is as on Solaris 11.4.])
+ fi
+
+ dnl Solaris 12 will maybe provide getlocalename_l. If it does, it will
+ dnl improve the implementation of gl_locale_name_thread(), by removing
+ dnl the use of undocumented structures.
+ case "$gt_cv_func_uselocale_works" in
+ *yes)
+ AC_CHECK_FUNCS([getlocalename_l])
+ ;;
+ esac
+
+ dnl This code is for platforms where the locale_t type does not provide access
+ dnl to the name of each locale category. This code has the drawback that it
+ dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale',
+ dnl which is a problem for GNU libunistring. Therefore try hard to avoid
+ dnl enabling this code!
+ gt_nameless_locales=no
+ case "$host_os" in
+ dnl It's needed on AIX 7.2.
+ aix*)
+ gt_nameless_locales=yes
+ AC_DEFINE([HAVE_NAMELESS_LOCALES], [1],
+ [Define if the locale_t type does not contain the name of each locale category.])
+ ;;
+ esac
+
+ dnl We cannot support uselocale() on platforms where the locale_t type is
+ dnl fake. So, set
+ dnl gt_good_uselocale = gt_working_uselocale && !gt_fake_locales.
+ if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then
+ gt_good_uselocale=yes
+ AC_DEFINE([HAVE_GOOD_USELOCALE], [1],
+ [Define if the uselocale exists, may be safely called, and returns sufficient information.])
+ else
+ gt_good_uselocale=no
+ fi
+
+ dnl Set gt_localename_enhances_locale_funcs to indicate whether localename.c
+ dnl overrides newlocale(), duplocale(), freelocale() to keep track of locale
+ dnl names.
+ if test $gt_good_uselocale = yes && test $gt_nameless_locales = yes; then
+ gt_localename_enhances_locale_funcs=yes
+ LOCALENAME_ENHANCE_LOCALE_FUNCS=1
+ AC_DEFINE([LOCALENAME_ENHANCE_LOCALE_FUNCS], [1],
+ [Define if localename.c overrides newlocale(), duplocale(), freelocale().])
+ else
+ gt_localename_enhances_locale_funcs=no
+ fi
+])
+
+dnl Tests whether uselocale() exists and is usable.
+dnl Sets gt_working_uselocale and defines HAVE_WORKING_USELOCALE.
+AC_DEFUN([gt_FUNC_USELOCALE],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ dnl Persuade glibc and Solaris <locale.h> to define 'locale_t'.
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_FUNCS_ONCE([uselocale])
+
+ dnl On AIX 7.2, the uselocale() function is not documented and leads to
+ dnl crashes in subsequent setlocale() invocations.
+ dnl In 2019, some versions of z/OS lack the locale_t type and have a broken
+ dnl uselocale function.
+ if test $ac_cv_func_uselocale = yes; then
+ AC_CHECK_HEADERS_ONCE([xlocale.h])
+ AC_CACHE_CHECK([whether uselocale works],
+ [gt_cv_func_uselocale_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <locale.h>
+#if HAVE_XLOCALE_H
+# include <xlocale.h>
+#endif
+locale_t loc1;
+int main ()
+{
+ uselocale (NULL);
+ setlocale (LC_ALL, "en_US.UTF-8");
+ return 0;
+}]])],
+ [gt_cv_func_uselocale_works=yes],
+ [gt_cv_func_uselocale_works=no],
+ [# Guess no on AIX and z/OS, yes otherwise.
+ case "$host_os" in
+ aix* | openedition*) gt_cv_func_uselocale_works="guessing no" ;;
+ *) gt_cv_func_uselocale_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ else
+ gt_cv_func_uselocale_works=no
+ fi
+ case "$gt_cv_func_uselocale_works" in
+ *yes)
+ gt_working_uselocale=yes
+ AC_DEFINE([HAVE_WORKING_USELOCALE], [1],
+ [Define if the uselocale function exists and may safely be called.])
+ ;;
+ *)
+ gt_working_uselocale=no
+ ;;
+ esac
+])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/intl.m4
^
|
@@ -1,15 +1,15 @@
-# intl.m4 serial 29 (gettext-0.19)
-dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
+# intl.m4 serial 44 (gettext-0.21)
+dnl Copyright (C) 1995-2014, 2016-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
@@ -20,8 +20,7 @@
AC_PREREQ([2.60])
dnl Checks for all prerequisites of the intl subdirectory,
-dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
-dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
+dnl except for LIBTOOL, USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
AC_DEFUN([AM_INTL_SUBDIR],
[
AC_REQUIRE([AC_PROG_INSTALL])dnl
@@ -29,7 +28,6 @@
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([gt_GLIBC2])dnl
- AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_REQUIRE([gl_VISIBILITY])dnl
AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl
AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl
@@ -41,9 +39,26 @@
AC_REQUIRE([gl_GLIBC21])dnl
AC_REQUIRE([gl_XSIZE])dnl
AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl
+ AC_REQUIRE([gt_INTL_THREAD_LOCALE_NAME])
AC_REQUIRE([gt_INTL_MACOSX])dnl
AC_REQUIRE([gl_EXTERN_INLINE])dnl
AC_REQUIRE([gt_GL_ATTRIBUTE])dnl
+ AC_REQUIRE([AC_C_FLEXIBLE_ARRAY_MEMBER])dnl
+
+ dnl In projects that use gnulib, use gl_PROG_AR_RANLIB.
+ dnl The '][' hides this use from 'aclocal'.
+ m4_ifdef([g][l_PROG_AR_RANLIB],
+ [AC_REQUIRE([g][l_PROG_AR_RANLIB])],
+ [AC_REQUIRE([AC_PROG_RANLIB])
+ dnl Use Automake-documented default values for AR and ARFLAGS, but prefer
+ dnl ${host}-ar over ar (useful for cross-compiling).
+ AC_CHECK_TOOL([AR], [ar], [ar])
+ if test -z "$ARFLAGS"; then
+ ARFLAGS='cr'
+ fi
+ AC_SUBST([AR])
+ AC_SUBST([ARFLAGS])
+ ])
dnl Support for automake's --enable-silent-rules.
case "$enable_silent_rules" in
@@ -58,8 +73,8 @@
[Define as the type of the result of subtracting two pointers, if the system doesn't define it.])
])
AC_CHECK_HEADERS([features.h stddef.h stdlib.h string.h])
- AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \
- snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
+ AC_CHECK_FUNCS([asprintf wprintf newlocale putenv setenv \
+ snprintf strnlen uselocale wcslen wcsnlen mbrtowc wcrtomb])
dnl Use the _snprintf function only if it is declared (because on NetBSD it
dnl is defined as a weak alias of snprintf; we prefer to use the latter).
@@ -104,6 +119,13 @@
AM_LANGINFO_CODESET
gt_LC_MESSAGES
+ if test $gt_nameless_locales = yes; then
+ HAVE_NAMELESS_LOCALES=1
+ else
+ HAVE_NAMELESS_LOCALES=0
+ fi
+ AC_SUBST([HAVE_NAMELESS_LOCALES])
+
dnl Compilation on mingw and Cygwin needs special Makefile rules, because
dnl 1. when we install a shared library, we must arrange to export
dnl auxiliary pointer variables for every exported variable,
@@ -135,18 +157,6 @@
AC_CHECK_TOOL([WINDRES], [windres])
fi
- dnl Determine whether when creating a library, "-lc" should be passed to
- dnl libtool or not. On many platforms, it is required for the libtool option
- dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool
- dnl in the *.la files - makes it impossible to create multithreaded programs,
- dnl because libtool also reorders the -lc to come before the -pthread, and
- dnl this disables pthread_create() <http://docs.hp.com/en/1896/pthreads.html>.
- case "$host_os" in
- hpux*) LTLIBC="" ;;
- *) LTLIBC="-lc" ;;
- esac
- AC_SUBST([LTLIBC])
-
dnl Rename some macros and functions used for locking.
AH_BOTTOM([
#define __libc_lock_t gl_lock_t
@@ -217,7 +227,6 @@
AC_REQUIRE([AC_FUNC_MMAP])dnl
AC_REQUIRE([gt_INTDIV0])dnl
AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl
- AC_REQUIRE([gt_INTTYPES_PRI])dnl
AC_REQUIRE([gl_LOCK])dnl
AC_LINK_IFELSE(
@@ -227,16 +236,9 @@
[AC_DEFINE([HAVE_BUILTIN_EXPECT], [1],
[Define to 1 if the compiler understands __builtin_expect.])])
- AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h])
+ AC_CHECK_HEADERS([inttypes.h limits.h unistd.h sys/param.h])
AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \
- stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \
- argz_stringify argz_next __fsetlocking])
-
- dnl Solaris 12 provides getlocalename_l, while Illumos doesn't have
- dnl it nor the equivalent.
- if test $ac_cv_func_uselocale = yes; then
- AC_CHECK_FUNCS([getlocalename_l])
- fi
+ stpcpy strcasecmp strdup strtoul tsearch __fsetlocking])
dnl Use the *_unlocked functions only if they are declared.
dnl (because some of them were defined without being declared in Solaris
@@ -248,33 +250,14 @@
dnl intl/plural.c is generated from intl/plural.y. It requires bison,
dnl because plural.y uses bison specific features. It requires at least
- dnl bison-2.7 for %define api.pure.
+ dnl bison-3.0 for %precedence.
dnl bison is only needed for the maintainer (who touches plural.y). But in
dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put
dnl the rule in general Makefile. Now, some people carelessly touch the
dnl files or have a broken "make" program, hence the plural.c rule will
dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not
dnl present or too old.
- AC_CHECK_PROGS([INTLBISON], [bison])
- if test -z "$INTLBISON"; then
- ac_verc_fail=yes
- else
- dnl Found it, now check the version.
- AC_MSG_CHECKING([version of bison])
-changequote(<<,>>)dnl
- ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
- case $ac_prog_version in
- '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
- 2.[7-9]* | [3-9].*)
-changequote([,])dnl
- ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
- *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
- esac
- AC_MSG_RESULT([$ac_prog_version])
- fi
- if test $ac_verc_fail = yes; then
- INTLBISON=:
- fi
+ gl_PROG_BISON([INTLBISON], [3.0])
])
dnl Copies _GL_UNUSED and _GL_ATTRIBUTE_PURE definitions from
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/intlmacosx.m4
^
|
@@ -1,15 +1,15 @@
-# intlmacosx.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2004-2014, 2016 Free Software Foundation, Inc.
+# intlmacosx.m4 serial 8 (gettext-0.20.2)
+dnl Copyright (C) 2004-2014, 2016, 2019-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
@@ -17,7 +17,7 @@
dnl Defines INTL_MACOSX_LIBS.
AC_DEFUN([gt_INTL_MACOSX],
[
- dnl Check for API introduced in Mac OS X 10.2.
+ dnl Check for API introduced in Mac OS X 10.4.
AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
[gt_cv_func_CFPreferencesCopyAppValue],
[gt_save_LIBS="$LIBS"
@@ -33,23 +33,32 @@
AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
[Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
fi
- dnl Check for API introduced in Mac OS X 10.3.
- AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
+ dnl Don't check for the API introduced in Mac OS X 10.5, CFLocaleCopyCurrent,
+ dnl because in macOS 10.13.4 it has the following behaviour:
+ dnl When two or more languages are specified in the
+ dnl "System Preferences > Language & Region > Preferred Languages" panel,
+ dnl it returns en_CC where CC is the territory (even when English is not among
+ dnl the preferred languages!). What we want instead is what
+ dnl CFLocaleCopyCurrent returned in earlier macOS releases and what
+ dnl CFPreferencesCopyAppValue still returns, namely ll_CC where ll is the
+ dnl first among the preferred languages and CC is the territory.
+ AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages],
[gt_save_LIBS="$LIBS"
LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <CoreFoundation/CFLocale.h>]],
- [[CFLocaleCopyCurrent();]])],
- [gt_cv_func_CFLocaleCopyCurrent=yes],
- [gt_cv_func_CFLocaleCopyCurrent=no])
+ [[CFLocaleCopyPreferredLanguages();]])],
+ [gt_cv_func_CFLocaleCopyPreferredLanguages=yes],
+ [gt_cv_func_CFLocaleCopyPreferredLanguages=no])
LIBS="$gt_save_LIBS"])
- if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
- AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
- [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+ if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1],
+ [Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.])
fi
INTL_MACOSX_LIBS=
- if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes \
+ || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then
INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
fi
AC_SUBST([INTL_MACOSX_LIBS])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/lcmessage.m4
^
|
@@ -1,16 +1,16 @@
-# lcmessage.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1995-2002, 2004-2005, 2008-2014, 2016 Free Software
-dnl Foundation, Inc.
+# lcmessage.m4 serial 8
+dnl Copyright (C) 1995-2002, 2004-2005, 2008-2014, 2016, 2019-2021 Free
+dnl Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/lib-ld.m4
^
|
@@ -1,5 +1,5 @@
-# lib-ld.m4 serial 7
-dnl Copyright (C) 1996-2003, 2009-2017 Free Software Foundation, Inc.
+# lib-ld.m4 serial 9
+dnl Copyright (C) 1996-2003, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -120,11 +120,14 @@
fi
case $host in
*-*-aix*)
- AC_EGREP_CPP([yes],
- [#if defined __powerpc64__ || defined _ARCH_PPC64
- yes
- #endif
- ],
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __powerpc64__ || defined _ARCH_PPC64
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
[# The compiler produces 64-bit code. Add option '-b64' so that the
# linker groks 64-bit object files.
case "$acl_cv_path_LD " in
@@ -133,6 +136,24 @@
esac
], [])
;;
+ sparc64-*-netbsd*)
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#if defined __sparcv9 || defined __arch64__
+ int ok;
+ #else
+ error fail
+ #endif
+ ]])],
+ [],
+ [# The compiler produces 32-bit code. Add option '-m elf32_sparc'
+ # so that the linker groks 32-bit object files.
+ case "$acl_cv_path_LD " in
+ *" -m elf32_sparc "*) ;;
+ *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;;
+ esac
+ ])
+ ;;
esac
])
LD="$acl_cv_path_LD"
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/lib-link.m4
^
|
@@ -1,12 +1,12 @@
-# lib-link.m4 serial 26 (gettext-0.18.2)
-dnl Copyright (C) 2001-2016 Free Software Foundation, Inc.
+# lib-link.m4 serial 32
+dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
-AC_PREREQ([2.54])
+AC_PREREQ([2.61])
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
@@ -124,8 +124,8 @@
dnl acl_hardcode_minus_L.
AC_DEFUN([AC_LIB_RPATH],
[
- dnl Tell automake >= 1.10 to complain if config.rpath is missing.
- m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ dnl Complain if config.rpath is missing.
+ AC_REQUIRE_AUX_FILE([config.rpath])
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
@@ -187,17 +187,17 @@
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
- dnl Autoconf >= 2.61 supports dots in --with options.
- pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
+ eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+ eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
])
- AC_ARG_WITH(P_A_C_K[-prefix],
-[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
- --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
+ AC_ARG_WITH(PACK[-prefix],
+[[ --with-]]PACK[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
+ --without-]]PACK[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
[
if test "X$withval" = "Xno"; then
use_additional=no
@@ -206,17 +206,23 @@
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
+ eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+ eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
- if test "$acl_libdirstem2" != "$acl_libdirstem" \
- && ! test -d "$withval/$acl_libdirstem"; then
- additional_libdir="$withval/$acl_libdirstem2"
- fi
+ additional_libdir2="$withval/$acl_libdirstem2"
+ additional_libdir3="$withval/$acl_libdirstem3"
fi
fi
])
+ if test "X$additional_libdir2" = "X$additional_libdir"; then
+ additional_libdir2=
+ fi
+ if test "X$additional_libdir3" = "X$additional_libdir"; then
+ additional_libdir3=
+ fi
dnl Search the library and its dependencies in $additional_libdir and
dnl $LDFLAGS. Using breadth-first-seach.
LIB[]NAME=
@@ -272,48 +278,54 @@
shrext=
fi
if test $use_additional = yes; then
- dir="$additional_libdir"
- dnl The same code as in the loop below:
- dnl First look for a shared library.
- if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext"
- else
- if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
- ver=`(cd "$dir" && \
- for f in "$libname$shrext".*; do echo "$f"; done \
- | sed -e "s,^$libname$shrext\\\\.,," \
- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
- | sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext.$ver"
+ for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do
+ if test "X$found_dir" = "X"; then
+ eval dir=\$$additional_libdir_variable
+ if test -n "$dir"; then
+ dnl The same code as in the loop below:
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
fi
- else
- eval library_names=\"$acl_library_names_spec\"
- for f in $library_names; do
- if test -f "$dir/$f"; then
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
found_dir="$dir"
- found_so="$dir/$f"
- break
+ found_a="$dir/$libname.$acl_libext"
fi
- done
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
fi
fi
- fi
- dnl Then look for a static library.
- if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
- found_dir="$dir"
- found_a="$dir/$libname.$acl_libext"
- fi
- fi
- if test "X$found_dir" != "X"; then
- if test -f "$dir/$libname.la"; then
- found_la="$dir/$libname.la"
- fi
- fi
+ done
fi
if test "X$found_dir" = "X"; then
for x in $LDFLAGS $LTLIB[]NAME; do
@@ -323,7 +335,7 @@
dir=`echo "X$x" | sed -e 's/^X-L//'`
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
+ if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
@@ -333,14 +345,14 @@
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
- if test -f "$dir/$f"; then
+ if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
@@ -351,7 +363,7 @@
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
+ if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
@@ -377,7 +389,8 @@
dnl standard /usr/lib.
if test "$enable_rpath" = no \
|| test "X$found_dir" = "X/usr/$acl_libdirstem" \
- || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then
dnl No hardcoding is needed.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
@@ -477,6 +490,13 @@
fi
additional_includedir="$basedir/include"
;;
+ */$acl_libdirstem3 | */$acl_libdirstem3/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
esac
if test "X$additional_includedir" != "X"; then
dnl Potentially add $additional_includedir to $INCNAME.
@@ -527,19 +547,21 @@
for dep in $dependency_libs; do
case "$dep" in
-L*)
- additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
- dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ dnl Potentially add $dependency_libdir to $LIBNAME and $LTLIBNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
dnl 3. if it's already present in $LDFLAGS or the already
dnl constructed $LIBNAME,
dnl 4. if it doesn't exist as a directory.
- if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
- && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \
+ && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \
+ && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then
haveit=
- if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
- || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+ if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \
+ || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
@@ -550,29 +572,29 @@
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
+ if test "X$x" = "X-L$dependency_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LIBNAME.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+ if test -d "$dependency_libdir"; then
+ dnl Really add $dependency_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$dependency_libdir"
fi
fi
haveit=
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
+ if test "X$x" = "X-L$dependency_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LTLIBNAME.
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+ if test -d "$dependency_libdir"; then
+ dnl Really add $dependency_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$dependency_libdir"
fi
fi
fi
@@ -609,7 +631,20 @@
;;
-l*)
dnl Handle this in the next round.
- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ dnl But on GNU systems, ignore -lc options, because
+ dnl - linking with libc is the default anyway,
+ dnl - linking with libc.a may produce an error
+ dnl "/usr/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie"
+ dnl or may produce an executable that always crashes, see
+ dnl <https://lists.gnu.org/archive/html/grep-devel/2020-09/msg00052.html>.
+ dep=`echo "X$dep" | sed -e 's/^X-l//'`
+ if test "X$dep" != Xc \
+ || case $host_os in
+ linux* | gnu* | k*bsd*-gnu) false ;;
+ *) true ;;
+ esac; then
+ names_next_round="$names_next_round $dep"
+ fi
;;
*.la)
dnl Handle this in the next round. Throw away the .la's
@@ -670,7 +705,6 @@
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
done
fi
- popdef([P_A_C_K])
popdef([PACKLIBS])
popdef([PACKUP])
popdef([PACK])
@@ -721,7 +755,8 @@
dir="$next"
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ && test "X$dir" != "X/usr/$acl_libdirstem2" \
+ && test "X$dir" != "X/usr/$acl_libdirstem3"; then
rpathdirs="$rpathdirs $dir"
fi
next=
@@ -731,7 +766,8 @@
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ && test "X$dir" != "X/usr/$acl_libdirstem2" \
+ && test "X$dir" != "X/usr/$acl_libdirstem3"; then
rpathdirs="$rpathdirs $dir"
fi
next= ;;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/lib-prefix.m4
^
|
@@ -1,18 +1,11 @@
-# lib-prefix.m4 serial 8
-dnl Copyright (C) 2001-2005, 2008-2017 Free Software Foundation, Inc.
+# lib-prefix.m4 serial 19
+dnl Copyright (C) 2001-2005, 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
dnl to access previously installed libraries. The basic assumption is that
dnl a user will want packages to use other packages he previously installed
@@ -32,9 +25,9 @@
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
- AC_LIB_ARG_WITH([lib-prefix],
-[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
- --without-lib-prefix don't search for libraries in includedir and libdir],
+ AC_ARG_WITH([lib-prefix],
+[[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir]],
[
if test "X$withval" = "Xno"; then
use_additional=no
@@ -154,88 +147,177 @@
])
dnl AC_LIB_PREPARE_MULTILIB creates
-dnl - a variable acl_libdirstem, containing the basename of the libdir, either
-dnl "lib" or "lib64" or "lib/64",
-dnl - a variable acl_libdirstem2, as a secondary possible value for
-dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
-dnl "lib/amd64".
+dnl - a function acl_is_expected_elfclass, that tests whether standard input
+dn; has a 32-bit or 64-bit ELF header, depending on the host CPU ABI,
+dnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing
+dnl the basename of the libdir to try in turn, either "lib" or "lib64" or
+dnl "lib/64" or "lib32" or "lib/sparcv9" or "lib/amd64" or similar.
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
[
- dnl There is no formal standard regarding lib and lib64.
- dnl On glibc systems, the current practice is that on a system supporting
+ dnl There is no formal standard regarding lib, lib32, and lib64.
+ dnl On most glibc systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
- dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
- dnl the compiler's default mode by looking at the compiler's library search
- dnl path. If at least one of its elements ends in /lib64 or points to a
- dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
- dnl Otherwise we use the default, namely "lib".
+ dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. However, on
+ dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go
+ dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib.
+ dnl We determine the compiler's default mode by looking at the compiler's
+ dnl library search path. If at least one of its elements ends in /lib64 or
+ dnl points to a directory whose absolute pathname ends in /lib64, we use that
+ dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default,
+ dnl namely "lib".
dnl On Solaris systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT])
+
+ AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf],
+ [AC_EGREP_CPP([Extensible Linking Format],
+ [#ifdef __ELF__
+ Extensible Linking Format
+ #endif
+ ],
+ [gl_cv_elf=yes],
+ [gl_cv_elf=no])
+ ])
+ if test $gl_cv_elf = yes; then
+ # Extract the ELF class of a file (5th byte) in decimal.
+ # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
+ if od -A x < /dev/null >/dev/null 2>/dev/null; then
+ # Use POSIX od.
+ func_elfclass ()
+ {
+ od -A n -t d1 -j 4 -N 1
+ }
+ else
+ # Use BSD hexdump.
+ func_elfclass ()
+ {
+ dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "'
+ echo
+ }
+ fi
+ # Use 'expr', not 'test', to compare the values of func_elfclass, because on
+ # Solaris 11 OpenIndiana and Solaris 11 OmniOS, the result is 001 or 002,
+ # not 1 or 2.
+changequote(,)dnl
+ case $HOST_CPU_C_ABI_32BIT in
+ yes)
+ # 32-bit ABI.
+ acl_is_expected_elfclass ()
+ {
+ expr "`func_elfclass | sed -e 's/[ ]//g'`" = 1 > /dev/null
+ }
+ ;;
+ no)
+ # 64-bit ABI.
+ acl_is_expected_elfclass ()
+ {
+ expr "`func_elfclass | sed -e 's/[ ]//g'`" = 2 > /dev/null
+ }
+ ;;
+ *)
+ # Unknown.
+ acl_is_expected_elfclass ()
+ {
+ :
+ }
+ ;;
+ esac
+changequote([,])dnl
+ else
+ acl_is_expected_elfclass ()
+ {
+ :
+ }
+ fi
+
dnl Allow the user to override the result by setting acl_cv_libdirstems.
AC_CACHE_CHECK([for the common suffixes of directories in the library search path],
[acl_cv_libdirstems],
- [acl_libdirstem=lib
+ [dnl Try 'lib' first, because that's the default for libdir in GNU, see
+ dnl <https://www.gnu.org/prep/standards/html_node/Directory-Variables.html>.
+ acl_libdirstem=lib
acl_libdirstem2=
+ acl_libdirstem3=
case "$host_os" in
solaris*)
dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
- dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+ dnl <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>.
dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
dnl symlink is missing, so we set acl_libdirstem2 too.
- AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
- [AC_EGREP_CPP([sixtyfour bits], [
-#ifdef _LP64
-sixtyfour bits
-#endif
- ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
- ])
- if test $gl_cv_solaris_64bit = yes; then
- acl_libdirstem=lib/64
+ if test $HOST_CPU_C_ABI_32BIT = no; then
+ acl_libdirstem2=lib/64
case "$host_cpu" in
- sparc*) acl_libdirstem2=lib/sparcv9 ;;
- i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ sparc*) acl_libdirstem3=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem3=lib/amd64 ;;
esac
fi
;;
*)
- dnl The result is a property of the system. However, non-system
- dnl compilers sometimes have odd library search paths. Therefore
- dnl prefer asking /usr/bin/gcc, if available, rather than $CC.
- searchpath=`(if test -f /usr/bin/gcc \
- && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \
- LC_ALL=C /usr/bin/gcc -print-search-dirs; \
- else \
- LC_ALL=C $CC -print-search-dirs; \
- fi) 2>/dev/null \
+ dnl If $CC generates code for a 32-bit ABI, the libraries are
+ dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64.
+ dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries
+ dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32.
+ dnl Find the compiler's search path. However, non-system compilers
+ dnl sometimes have odd library search paths. But we can't simply invoke
+ dnl '/usr/bin/gcc -print-search-dirs' because that would not take into
+ dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS.
+ searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \
| sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test $HOST_CPU_C_ABI_32BIT != no; then
+ # 32-bit or unknown ABI.
+ if test -d /usr/lib32; then
+ acl_libdirstem2=lib32
+ fi
+ fi
+ if test $HOST_CPU_C_ABI_32BIT != yes; then
+ # 64-bit or unknown ABI.
+ if test -d /usr/lib64; then
+ acl_libdirstem3=lib64
+ fi
+ fi
if test -n "$searchpath"; then
acl_save_IFS="${IFS= }"; IFS=":"
for searchdir in $searchpath; do
if test -d "$searchdir"; then
case "$searchdir" in
- */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;;
+ */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;;
*/../ | */.. )
# Better ignore directories of this form. They are misleading.
;;
*) searchdir=`cd "$searchdir" && pwd`
case "$searchdir" in
- */lib64 ) acl_libdirstem=lib64 ;;
+ */lib32 ) acl_libdirstem2=lib32 ;;
+ */lib64 ) acl_libdirstem3=lib64 ;;
esac ;;
esac
fi
done
IFS="$acl_save_IFS"
+ if test $HOST_CPU_C_ABI_32BIT = yes; then
+ # 32-bit ABI.
+ acl_libdirstem3=
+ fi
+ if test $HOST_CPU_C_ABI_32BIT = no; then
+ # 64-bit ABI.
+ acl_libdirstem2=
+ fi
fi
;;
esac
test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
- acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2"
+ test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem"
+ acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3"
])
- # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2.
+ dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and
+ dnl acl_libdirstem3.
+changequote(,)dnl
acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'`
- acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'`
+ acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'`
+ acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'`
+changequote([,])dnl
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/libcurl.m4
^
|
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 2006, David Shaw <dshaw@jabberwocky.com>
+# Copyright (C) 2006 - 2020, David Shaw <dshaw@jabberwocky.com>
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/libgcrypt.m4
^
|
@@ -1,5 +1,5 @@
# libgcrypt.m4 - Autoconf macros to detect libgcrypt
-# Copyright (C) 2002, 2003, 2004, 2011, 2014 g10 Code GmbH
+# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020 g10 Code GmbH
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
@@ -9,17 +9,17 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
-# Last-changed: 2014-10-02
+# Last-changed: 2020-09-27
dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
-dnl MINIMUM-VERSION is a string with the version number optionalliy prefixed
+dnl MINIMUM-VERSION is a string with the version number optionally prefixed
dnl with the API version to also check the API compatibility. Example:
dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed
dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
-dnl this feature prevents building against newer versions of libgcrypt
+dnl this features allows to prevent build against newer versions of libgcrypt
dnl with a changed API.
dnl
dnl If a prefix option is not used, the config script is first
@@ -30,14 +30,26 @@
AC_DEFUN([AM_PATH_LIBGCRYPT],
[ AC_REQUIRE([AC_CANONICAL_HOST])
AC_ARG_WITH(libgcrypt-prefix,
- AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
+ AS_HELP_STRING([--with-libgcrypt-prefix=PFX],
[prefix where LIBGCRYPT is installed (optional)]),
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
if test x"${LIBGCRYPT_CONFIG}" = x ; then
if test x"${libgcrypt_config_prefix}" != x ; then
LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config"
- else
- case "${SYSROOT}" in
+ fi
+ fi
+
+ use_gpgrt_config=""
+ if test x"${LIBGCRYPT_CONFIG}" = x -a x"$GPGRT_CONFIG" != x -a "$GPGRT_CONFIG" != "no"; then
+ if $GPGRT_CONFIG libgcrypt --exists; then
+ LIBGCRYPT_CONFIG="$GPGRT_CONFIG libgcrypt"
+ AC_MSG_NOTICE([Use gpgrt-config as libgcrypt-config])
+ use_gpgrt_config=yes
+ fi
+ fi
+ if test -z "$use_gpgrt_config"; then
+ if test x"${LIBGCRYPT_CONFIG}" = x ; then
+ case "${SYSROOT}" in
/*)
if test -x "${SYSROOT}/bin/libgcrypt-config" ; then
LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config"
@@ -48,11 +60,11 @@
*)
AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
;;
- esac
- fi
+ esac
+ fi
+ AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
fi
- AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
tmp=ifelse([$1], ,1:1.2.0,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
@@ -71,7 +83,11 @@
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_libgcrypt_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
- libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ if test -z "$use_gpgrt_config"; then
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ else
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --modversion`
+ fi
major=`echo $libgcrypt_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $libgcrypt_config_version | \
@@ -103,7 +119,11 @@
# If we have a recent libgcrypt, we should also check that the
# API is compatible
if test "$req_libgcrypt_api" -gt 0 ; then
- tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ if test -z "$use_gpgrt_config"; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ else
+ tmp=`$LIBGCRYPT_CONFIG --variable=api_version 2>/dev/null || echo 0`
+ fi
if test "$tmp" -gt 0 ; then
AC_MSG_CHECKING([LIBGCRYPT API version])
if test "$req_libgcrypt_api" -eq "$tmp" ; then
@@ -119,12 +139,16 @@
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
ifelse([$2], , :, [$2])
- libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ if test -z "$use_gpgrt_config"; then
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ else
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --variable=host 2>/dev/null || echo none`
+ fi
if test x"$libgcrypt_config_host" != xnone ; then
if test x"$libgcrypt_config_host" != x"$host" ; then
AC_MSG_WARN([[
***
-*** The config script $LIBGCRYPT_CONFIG was
+*** The config script "$LIBGCRYPT_CONFIG" was
*** built for $libgcrypt_config_host and thus may not match the
*** used host $host.
*** You may want to use the configure option --with-libgcrypt-prefix
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/lock.m4
^
|
@@ -1,5 +1,5 @@
-# lock.m4 serial 13 (gettext-0.18.2)
-dnl Copyright (C) 2005-2016 Free Software Foundation, Inc.
+# lock.m4 serial 14
+dnl Copyright (C) 2005-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -12,11 +12,16 @@
if test "$gl_threads_api" = posix; then
# OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the
# pthread_rwlock_* functions.
+ has_rwlock=false
AC_CHECK_TYPE([pthread_rwlock_t],
- [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
+ [has_rwlock=true
+ AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
[Define if the POSIX multithreading library has read/write locks.])],
[],
[#include <pthread.h>])
+ if $has_rwlock; then
+ gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
+ fi
# glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM(
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/longlong.m4
^
|
@@ -1,14 +1,15 @@
-# longlong.m4 serial 17
-dnl Copyright (C) 1999-2007, 2009-2016 Free Software Foundation, Inc.
+# longlong.m4 serial 19
+dnl Copyright (C) 1999-2007, 2009-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Paul Eggert.
+AC_PREREQ([2.62])
+
# Define HAVE_LONG_LONG_INT if 'long long int' works.
-# This fixes a bug in Autoconf 2.61, and can be faster
-# than what's in Autoconf 2.62 through 2.68.
+# This can be faster than what's in Autoconf 2.62 through 2.68.
# Note: If the type 'long long int' exists but is only 32 bits large
# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
@@ -27,12 +28,12 @@
dnl nobody cross compiles for this platform as far as we know.
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
- [[@%:@include <limits.h>
- @%:@ifndef LLONG_MAX
- @%:@ define HALF \
+ [[#include <limits.h>
+ #ifndef LLONG_MAX
+ # define HALF \
(1LL << (sizeof (long long int) * CHAR_BIT - 2))
- @%:@ define LLONG_MAX (HALF - 1 + HALF)
- @%:@endif]],
+ # define LLONG_MAX (HALF - 1 + HALF)
+ #endif]],
[[long long int n = 1;
int i;
for (i = 0; ; i++)
@@ -56,8 +57,7 @@
])
# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
-# This fixes a bug in Autoconf 2.61, and can be faster
-# than what's in Autoconf 2.62 through 2.68.
+# This can be faster than what's in Autoconf 2.62 through 2.68.
# Note: If the type 'unsigned long long int' exists but is only 32 bits
# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/mhd_check_func.m4
^
|
@@ -0,0 +1,80 @@
+# SYNOPSIS
+#
+# MHD_CHECK_FUNC([FUNCTION_NAME],
+# [INCLUDES=AC_INCLUDES_DEFAULT], [CHECK_CODE],
+# [ACTION-IF-AVAILABLE], [ACTION-IF-NOT-AVAILABLE],
+# [ADDITIONAL_LIBS])
+#
+# DESCRIPTION
+#
+# This macro checks for presence of specific function by including
+# specified headers and compiling and linking CHECK_CODE.
+# This check both declaration and presence in library.
+# Unlike AC_CHECK_FUNCS macro, this macro do not produce false
+# negative result if function is declared with specific calling
+# conventions like __stdcall' or attribute like
+# __attribute__((__dllimport__)) and linker failed to build test
+# program if library contains function with calling conventions
+# different from declared.
+# By using definition from provided headers, this macro ensures that
+# correct calling convention is used for detection.
+#
+# Example usage:
+#
+# MHD_CHECK_FUNC([memmem],
+# [[#include <string.h>]],
+# [const void *ptr = memmem("aa", 2, "a", 1); (void)ptr;],
+# [var_use_memmem='yes'], [var_use_memmem='no'])
+#
+# Defined cache variable used in check so if any test will not work
+# correctly on some platform, user may simply fix it by giving cache
+# variable in configure parameters, for example:
+#
+# ./configure mhd_cv_func_memmem_have=no
+#
+# This simplify building from source on exotic platforms as patching
+# of configure.ac is not required to change results of tests.
+#
+# LICENSE
+#
+# Copyright (c) 2019 Karlson2k (Evgeny Grin) <k2k@narod.ru>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 1
+
+AC_DEFUN([MHD_CHECK_FUNC],[dnl
+ AC_PREREQ([2.64])dnl for AS_VAR_IF, m4_ifblank, m4_ifnblank
+ m4_ifblank(m4_translit([$1],[()],[ ]), [m4_fatal([First macro argument must not be empty])])dnl
+ m4_ifblank([$3], [m4_fatal([Third macro argument must not be empty])])dnl
+ m4_bmatch(m4_normalize([$1]), [\s],dnl
+ [m4_fatal([First macro argument must not contain whitespaces])])dnl
+ m4_if(m4_index([$3], m4_normalize(m4_translit([$1],[()],[ ]))), [-1], dnl
+ [m4_fatal([CHECK_CODE parameter (third macro argument) do not contain ']m4_normalize([$1])[' token])])dnl
+ AS_VAR_PUSHDEF([cv_Var], [mhd_cv_func_]m4_bpatsubst(m4_normalize(m4_translit([$1],[()],[ ])),[[^a-zA-Z0-9]],[_]))dnl
+ dnl
+ AC_CACHE_CHECK([for function $1], [cv_Var],
+ [dnl
+ m4_ifnblank([$6],[dnl
+ mhd_check_func_SAVE_LIBS="$LIBS"
+ LIBS="$LIBS m4_normalize([$6])"
+ ])dnl
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([m4_default_nblank([$2],[AC_INCLUDES_DEFAULT])], [$3]) ],
+ [AS_VAR_SET([cv_Var],["yes"])], [AS_VAR_SET([cv_Var],["no"])] )
+ m4_ifnblank([$6],[dnl
+ LIBS="${mhd_check_func_SAVE_LIBS}"
+ AS_UNSET([mhd_check_func_SAVE_LIBS])
+ ])dnl
+ ])
+ AS_VAR_IF([cv_Var], ["yes"],
+ [AC_DEFINE([[HAVE_]]m4_bpatsubst(m4_toupper(m4_normalize(m4_translit([$1],[()],[ ]))),[[^A-Z0-9]],[_]),
+ [1], [Define to 1 if you have the `]m4_normalize(m4_translit([$1],[()],[ ]))[' function.])
+ m4_n([$4])dnl
+ ], [$5])
+ AS_VAR_POPDEF([cv_Var])dnl
+])
+
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/mhd_shutdown_socket_trigger.m4
^
|
@@ -18,16 +18,16 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 2
+#serial 3
AC_DEFUN([MHD_CHECK_SOCKET_SHUTDOWN_TRIGGER],[dnl
AC_PREREQ([2.64])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AX_PTHREAD])dnl
- AC_CHECK_HEADERS([sys/time.h],[AC_CHECK_FUNCS([[gettimeofday]])],[], [AC_INCLUDES_DEFAULT])
- AC_CHECK_HEADERS([time.h],[AC_CHECK_FUNCS([[nanosleep]])],[], [AC_INCLUDES_DEFAULT])
- AC_CHECK_HEADERS([unistd.h],[AC_CHECK_FUNCS([[usleep]])],[], [AC_INCLUDES_DEFAULT])
+ AC_CHECK_HEADERS([sys/time.h],[AC_CHECK_FUNCS([gettimeofday])],[], [AC_INCLUDES_DEFAULT])
+ AC_CHECK_HEADERS([time.h],[AC_CHECK_FUNCS([nanosleep])],[], [AC_INCLUDES_DEFAULT])
+ AC_CHECK_HEADERS([unistd.h],[AC_CHECK_FUNCS([usleep])],[], [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([string.h sys/types.h sys/socket.h netinet/in.h time.h sys/select.h netinet/tcp.h],[],[], [AC_INCLUDES_DEFAULT])
AC_CACHE_CHECK([[whether shutdown of listen socket trigger select()]],
[[mhd_cv_host_shtdwn_trgr_select]], [dnl
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/mhd_sys_extentions.m4
^
|
@@ -40,263 +40,57 @@
#
# LICENSE
#
-# Copyright (c) 2016 Karlson2k (Evgeny Grin) <k2k@narod.ru>
+# Copyright (c) 2016, 2017 Karlson2k (Evgeny Grin) <k2k@narod.ru>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 1
+#serial 2
AC_DEFUN([MHD_SYS_EXT],[dnl
- AC_PREREQ([2.64])dnl for AS_VAR_IF, m4_ifnblank
+ AC_PREREQ([2.64])dnl for AS_VAR_IF, AS_VAR_SET_IF, m4_ifnblank
AC_LANG_PUSH([C])dnl Use C language for simplicity
- mhd_mse_added_exts_flags=""
- mhd_mse_added_prolog=""
- MHD_CHECK_DEFINED([[_XOPEN_SOURCE]], [], [dnl
- AC_CACHE_CHECK([[whether predefined value of _XOPEN_SOURCE is more or equal 500]],
- [[mhd_cv_macro__xopen_source_def_fiveh]], [dnl
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#if _XOPEN_SOURCE+0 < 500
-#error Value of _XOPEN_SOURCE is less than 500
-choke me now;
-#endif
- ]],[[int i = 0; i++]])],dnl
- [[mhd_cv_macro__xopen_source_def_fiveh="yes"]],
- [[mhd_cv_macro__xopen_source_def_fiveh="no"]]
- )
- ])
- AS_VAR_IF([mhd_cv_macro__xopen_source_def_fiveh], [["no"]], [dnl
- _MHD_XOPEN_ADD([])
- ])
- ],
- [
- dnl Some platforms (namely: Solaris) use '==' checks instead of '>='
- dnl for _XOPEN_SOURCE, resulting that unknown for platform values are
- dnl interpreted as oldest and platform expose reduced number of
- dnl interfaces. Next checks will ensure that platform recognise
- dnl requested mode instead of blindly define high number that can
- dnl be simply ignored by platform.
- MHD_CHECK_ACCEPT_DEFINE([[_XOPEN_SOURCE]], [[700]], [], [dnl
- AC_CACHE_CHECK([[whether _XOPEN_SOURCE with value 700 really enable POSIX.1-2008/SUSv4 features]],
- [[mhd_cv_define__xopen_source_sevenh_works]], [dnl
- _MHD_CHECK_XOPEN_ENABLE([[700]], [
-_MHD_BASIC_INCLUDES
-[
-/* Check will be passed if ALL features are avalable
- * and failed if ANY feature is not avalable. */
-int main()
-{
-
-#ifndef stpncpy
- (void) stpncpy;
-#endif
-#ifndef strnlen
- (void) strnlen;
-#endif
-
-#if !defined(__NetBSD__) && !defined(__OpenBSD__)
-/* NetBSD and OpenBSD didn't implement wcsnlen() for some reason. */
-#ifndef wcsnlen
- (void) wcsnlen;
-#endif
-#endif
-
-#ifdef __CYGWIN__
-/* The only depend function on Cygwin, but missing on some other platforms */
-#ifndef strndup
- (void) strndup;
-#endif
-#endif
-
-#ifndef __sun
-/* illumos forget to uncomment some _XPG7 macros. */
-#ifndef renameat
- (void) renameat;
-#endif
-
-#ifndef getline
- (void) getline;
-#endif
-#endif /* ! __sun */
-
-/* gmtime_r() becomes mandatory only in POSIX.1-2008. */
-#ifndef gmtime_r
- (void) gmtime_r;
-#endif
-
-/* unsetenv() actually defined in POSIX.1-2001 so it
- * must be present with _XOPEN_SOURCE == 700 too. */
-#ifndef unsetenv
- (void) unsetenv;
-#endif
-
- return 0;
-}
- ]],
- [[mhd_cv_define__xopen_source_sevenh_works="yes"]],
- [[mhd_cv_define__xopen_source_sevenh_works="no"]]
- )dnl
- ])dnl
- ])
- AS_IF([[test "x$mhd_cv_define__xopen_source_accepted_700" = "xyes" &&
- test "x$mhd_cv_define__xopen_source_sevenh_works" = "xyes"]], [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_SOURCE]], [[700]])
- ], [dnl
- MHD_CHECK_ACCEPT_DEFINE([[_XOPEN_SOURCE]], [[600]], [], [dnl
- AC_CACHE_CHECK([[whether _XOPEN_SOURCE with value 600 really enable POSIX.1-2001/SUSv3 features]],
- [[mhd_cv_define__xopen_source_sixh_works]], [dnl
- _MHD_CHECK_XOPEN_ENABLE([[600]], [
-_MHD_BASIC_INCLUDES
-[
-/* Check will be passed if ALL features are available
- * and failed if ANY feature is not available. */
-int main()
-{
-
-#ifndef setenv
- (void) setenv;
-#endif
-
-#ifndef __NetBSD__
-#ifndef vsscanf
- (void) vsscanf;
-#endif
-#endif
-
-/* Availability of next features varies, but they all must be present
- * on platform with support for _XOPEN_SOURCE = 600. */
-
-/* vsnprintf() should be available with _XOPEN_SOURCE >= 500, but some platforms
- * provide it only with _POSIX_C_SOURCE >= 200112 (autodefined when
- * _XOPEN_SOURCE >= 600) where specification of vsnprintf() is aligned with
- * ISO C99 while others platforms defined it with even earlier standards. */
-#ifndef vsnprintf
- (void) vsnprintf;
-#endif
-
-/* On platforms that prefer POSIX over X/Open, fseeko() is available
- * with _POSIX_C_SOURCE >= 200112 (autodefined when _XOPEN_SOURCE >= 600).
- * On other platforms it should be available with _XOPEN_SOURCE >= 500. */
-#ifndef fseeko
- (void) fseeko;
-#endif
-
-/* F_GETOWN must be defined with _XOPEN_SOURCE >= 600, but some platforms
- * define it with _XOPEN_SOURCE >= 500. */
-#ifndef F_GETOWN
-#error F_GETOWN is not defined
-choke me now;
-#endif
- return 0;
-}
- ]],
- [[mhd_cv_define__xopen_source_sixh_works="yes"]],
- [[mhd_cv_define__xopen_source_sixh_works="no"]]
- )dnl
- ])dnl
- ])
- AS_IF([[test "x$mhd_cv_define__xopen_source_accepted_600" = "xyes" &&
- test "x$mhd_cv_define__xopen_source_sixh_works" = "xyes"]], [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_SOURCE]], [[600]])
- ], [dnl
- MHD_CHECK_ACCEPT_DEFINE([[_XOPEN_SOURCE]], [[500]], [], [dnl
- AC_CACHE_CHECK([[whether _XOPEN_SOURCE with value 500 really enable SUSv2/XPG5 features]],
- [mhd_cv_define__xopen_source_fiveh_works], [dnl
- _MHD_CHECK_XOPEN_ENABLE([[500]], [
-_MHD_BASIC_INCLUDES
-[
-/* Check will be passed if ALL features are available
- * and failed if ANY feature is not available. */
-int main()
-{
-/* It's not easy to write reliable test for _XOPEN_SOURCE = 500 as
- * platforms not always precisely follow this standard and some
- * functions are already deprecated in later standards. */
-
-/* Availability of next features varies, but they all must be present
- * on platform with correct support for _XOPEN_SOURCE = 500. */
-
-/* Mandatory with _XOPEN_SOURCE >= 500 but as XSI extension available
- * with much older standards. */
-#ifndef ftruncate
- (void) ftruncate;
-#endif
-
-/* Added with _XOPEN_SOURCE >= 500 but was available in some standards
- * before. XSI extension. */
-#ifndef pread
- (void) pread;
-#endif
-
-#ifndef __APPLE__
-/* Actually comes from XPG4v2 and must be available
- * with _XOPEN_SOURCE >= 500 as well. */
-#ifndef symlink
- (void) symlink;
-#endif
+ mhd_mse_sys_ext_defines=""
+ mhd_mse_sys_ext_flags=""
-/* Actually comes from XPG4v2 and must be available
- * with _XOPEN_SOURCE >= 500 as well. XSI extension. */
-#ifndef strdup
- (void) strdup;
-#endif
-#endif /* ! __APPLE__ */
- return 0;
-}
- ]],
- [[mhd_cv_define__xopen_source_fiveh_works="yes"]],
- [[mhd_cv_define__xopen_source_fiveh_works="no"]]
- )dnl
- ])dnl
- ])
- AS_IF([[test "x$mhd_cv_define__xopen_source_accepted_500" = "xyes" && ]dnl
- [test "x$mhd_cv_define__xopen_source_fiveh_works" = "xyes"]], [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_SOURCE]], [[500]])
- ],
- [
- [#] Earlier standards are widely supported, so just define macros to maximum value
- [#] which do not break headers.
- _MHD_XOPEN_ADD([[#define _XOPEN_SOURCE 1]])
- AC_CACHE_CHECK([[whether headers accept _XOPEN_SOURCE with value 1]],
- [mhd_cv_define__xopen_source_accepted_1], [dnl
- AS_IF([[test "x$mhd_cv_define__xopen_source_extended_accepted" = "xyes" || ]dnl
- [test "x$mhd_cv_define__xopen_version_accepted" = "xyes"]],
- [[mhd_cv_define__xopen_source_accepted_1="yes"]],
- [
- MHD_CHECK_BASIC_HEADERS([[#define _XOPEN_SOURCE 1]],
- [[mhd_cv_define__xopen_source_accepted_1="yes"]],
- [[mhd_cv_define__xopen_source_accepted_1="no"]])
- ])
- ])
- AS_VAR_IF([[mhd_cv_define__xopen_source_accepted_1]], [["yes"]], [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_SOURCE]], [[1]])
- ])
- ])
- ])
- ])
- ])
- dnl Add other extensions.
+ dnl Check platform-specific extensions.
dnl Use compiler-based test for determinig target.
dnl Always add _GNU_SOURCE if headers allow.
MHD_CHECK_DEF_AND_ACCEPT([[_GNU_SOURCE]], [],
- [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_GNU_SOURCE]])])
+ [[${mhd_mse_sys_ext_defines}]], [mhd_cv_macro_add__gnu_source="no"],
+ [mhd_cv_macro_add__gnu_source="yes"],
+ [mhd_cv_macro_add__gnu_source="no"]
+ )
+ AS_VAR_IF([mhd_cv_macro_add__gnu_source], ["yes"],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_GNU_SOURCE]])
+ ]
+ )
dnl __BSD_VISIBLE is actually a small hack for FreeBSD.
- dnl Funny that it's used in Android headers too.
+ dnl Funny that it's used in some Android versions too.
AC_CACHE_CHECK([[whether to try __BSD_VISIBLE macro]],
[[mhd_cv_macro_try___bsd_visible]], [dnl
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#if !defined(__FreeBSD__) && !defined (__ANDROID__)
-#error Target is not FreeBSD or Android
+/* Warning: test with inverted logic! */
+#ifdef __FreeBSD__
+#error Target FreeBSD
choke me now;
-#endif
+#endif /* __FreeBSD__ */
+
+#ifdef __ANDROID__
+#include <android/api-level.h>
+#ifndef __ANDROID_API_O__
+#error Target is Android NDK before R14
+choke me now;
+#endif /* ! __ANDROID_API_O__ */
+#endif /* __ANDROID__ */
]],[])],
- [[mhd_cv_macro_try___bsd_visible="yes"]],
- [[mhd_cv_macro_try___bsd_visible="no"]]
+ [[mhd_cv_macro_try___bsd_visible="no"]],
+ [[mhd_cv_macro_try___bsd_visible="yes"]]
)
])
AS_VAR_IF([[mhd_cv_macro_try___bsd_visible]], [["yes"]],
@@ -304,20 +98,12 @@
AC_CACHE_CHECK([[whether __BSD_VISIBLE is already defined]],
[[mhd_cv_macro___bsd_visible_defined]], [dnl
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-${mhd_mse_added_prolog}
+${mhd_mse_sys_ext_defines}
/* Warning: test with inverted logic! */
#ifdef __BSD_VISIBLE
#error __BSD_VISIBLE is defined
choke me now;
#endif
-#ifdef __ANDROID__
-/* if __BSD_VISIBLE is not defined, Android usually defines it to 1 */
-#include <stdio.h>
-#if defined(__BSD_VISIBLE) && __BSD_VISIBLE == 1
-#error __BSD_VISIBLE is autodefined by headers to value 1
-choke me now;
-#endif
-#endif
]],[])
],
[[mhd_cv_macro___bsd_visible_defined="no"]],
@@ -327,61 +113,73 @@
AS_VAR_IF([[mhd_cv_macro___bsd_visible_defined]], [["yes"]], [[:]],
[dnl
MHD_CHECK_ACCEPT_DEFINE(
- [[__BSD_VISIBLE]], [], [[${mhd_mse_added_prolog}]],
- [_MHD_SYS_EXT_ADD_FLAG([[__BSD_VISIBLE]])]
+ [[__BSD_VISIBLE]], [], [[${mhd_mse_sys_ext_defines}]],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[__BSD_VISIBLE]])
+ ]
)dnl
])
])
dnl _DARWIN_C_SOURCE enables additional functionality on Darwin.
- MHD_CHECK_DEFINED_MSG([[__APPLE__]], [[${mhd_mse_added_prolog}]],
+ MHD_CHECK_DEFINED_MSG([[__APPLE__]], [[${mhd_mse_sys_ext_defines}]],
[[whether to try _DARWIN_C_SOURCE macro]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[_DARWIN_C_SOURCE]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_DARWIN_C_SOURCE]])]
+ [[_DARWIN_C_SOURCE]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_DARWIN_C_SOURCE]])
+ ]
)dnl
])
dnl __EXTENSIONS__ unlocks almost all interfaces on Solaris.
- MHD_CHECK_DEFINED_MSG([[__sun]], [[${mhd_mse_added_prolog}]],
+ MHD_CHECK_DEFINED_MSG([[__sun]], [[${mhd_mse_sys_ext_defines}]],
[[whether to try __EXTENSIONS__ macro]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[__EXTENSIONS__]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[__EXTENSIONS__]])]
+ [[__EXTENSIONS__]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[__EXTENSIONS__]])
+ ]
)dnl
])
dnl _NETBSD_SOURCE switch on almost all headers definitions on NetBSD.
- MHD_CHECK_DEFINED_MSG([[__NetBSD__]], [[${mhd_mse_added_prolog}]],
+ MHD_CHECK_DEFINED_MSG([[__NetBSD__]], [[${mhd_mse_sys_ext_defines}]],
[[whether to try _NETBSD_SOURCE macro]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[_NETBSD_SOURCE]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_NETBSD_SOURCE]])]
+ [[_NETBSD_SOURCE]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_NETBSD_SOURCE]])
+ ]
)dnl
])
dnl _BSD_SOURCE currently used only on OpenBSD to unhide functions.
- MHD_CHECK_DEFINED_MSG([[__OpenBSD__]], [[${mhd_mse_added_prolog}]],
+ MHD_CHECK_DEFINED_MSG([[__OpenBSD__]], [[${mhd_mse_sys_ext_defines}]],
[[whether to try _BSD_SOURCE macro]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[_BSD_SOURCE]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_BSD_SOURCE]])]
+ [[_BSD_SOURCE]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_BSD_SOURCE]])
+ ]
)dnl
])
dnl _TANDEM_SOURCE unhides most functions on NonStop OS
dnl (which comes from Tandem Computers decades ago).
- MHD_CHECK_DEFINED_MSG([[__TANDEM]], [[${mhd_mse_added_prolog}]],
+ MHD_CHECK_DEFINED_MSG([[__TANDEM]], [[${mhd_mse_sys_ext_defines}]],
[[whether to try _TANDEM_SOURCE macro]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[_TANDEM_SOURCE]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_TANDEM_SOURCE]])]
+ [[_TANDEM_SOURCE]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_TANDEM_SOURCE]])
+ ]
)dnl
])
@@ -402,19 +200,140 @@
AS_VAR_IF([[mhd_cv_macro_try__all_source]], [["yes"]],
[dnl
MHD_CHECK_DEF_AND_ACCEPT(
- [[_ALL_SOURCE]], [], [[${mhd_mse_added_prolog}]], [],
- [_MHD_SYS_EXT_ADD_FLAG([[_TANDEM_SOURCE]])]
+ [[_ALL_SOURCE]], [], [[${mhd_mse_sys_ext_defines}]], [],
+ [
+ _MHD_SYS_EXT_VAR_ADD_FLAG([[mhd_mse_sys_ext_defines]], [[mhd_mse_sys_ext_flags]], [[_ALL_SOURCE]])
+ ]
+ )dnl
+ ])
+
+ mhd_mse_xopen_features=""
+ mhd_mse_xopen_defines=""
+ mhd_mse_xopen_flags=""
+
+ AC_CACHE_CHECK([[whether _XOPEN_SOURCE is already defined]],
+ [[mhd_cv_macro__xopen_source_defined]], [
+ _MHD_CHECK_DEFINED([[_XOPEN_SOURCE]], [[${mhd_mse_sys_ext_defines}]],
+ [[mhd_cv_macro__xopen_source_defined="yes"]],
+ [[mhd_cv_macro__xopen_source_defined="no"]]
+ )
+ ]
+ )
+ AS_VAR_IF([[mhd_cv_macro__xopen_source_defined]], [["no"]],
+ [
+ dnl Some platforms (namely: Solaris) use '==' checks instead of '>='
+ dnl for _XOPEN_SOURCE, resulting that unknown for platform values are
+ dnl interpreted as oldest and platform expose reduced number of
+ dnl interfaces. Next checks will ensure that platform recognise
+ dnl requested mode instead of blindly define high number that can
+ dnl be simply ignored by platform.
+ _MHD_CHECK_POSIX2008([[mhd_mse_xopen_defines]],
+ [[mhd_mse_xopen_flags]],
+ [[${mhd_mse_sys_ext_defines}]],
+ [mhd_mse_xopen_features="${mhd_cv_headers_posix2008}"],
+ [
+ _MHD_CHECK_POSIX2001([[mhd_mse_xopen_defines]],
+ [[mhd_mse_xopen_flags]],
+ [[${mhd_mse_sys_ext_defines}]],
+ [mhd_mse_xopen_features="${mhd_cv_headers_posix2001}"],
+ [
+ _MHD_CHECK_SUSV2([[mhd_mse_xopen_defines]],
+ [[mhd_mse_xopen_flags]],
+ [[${mhd_mse_sys_ext_defines}]],
+ [mhd_mse_xopen_features="${mhd_cv_headers_susv2}"],
+ [mhd_mse_xopen_features="${mhd_cv_headers_susv2}"]
+ )
+ ]
+ )
+ ]
+ )
+ ]
+ )
+
+ AS_IF([[test "x${mhd_cv_macro__xopen_source_defined}" = "xno" && \
+ test "x${mhd_cv_macro__xopen_source_def_fiveh}" = "xno" || \
+ test "x${mhd_mse_xopen_features}" = "xnot available" ]],
+ [
+ _MHD_XOPEN_VAR_ADD([mhd_mse_xopen_defines], [mhd_mse_xopen_flags], [${mhd_mse_sys_ext_defines}])
+ ]
+ )
+
+ mhd_mse_sys_features_src="
+#ifdef __APPLE__
+#include <sys/socket.h>
+#else
+#error No useful system features.
+choke me now;
+#endif
+
+int main()
+{
+#ifdef __APPLE__
+#ifndef sendfile
+ (void) sendfile;
+#endif
+#endif
+ return 0;
+}
+"
+ AC_CACHE_CHECK([[for useful system-specific features]],
+ [[mhd_cv_headers_useful_features_present]], [dnl
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+${mhd_mse_sys_ext_defines}
+${mhd_mse_sys_features_src}
+ ]])],
+ [[mhd_cv_headers_useful_features_present="yes"]],
+ [[mhd_cv_headers_useful_features_present="no"]]
)dnl
])
+ AS_VAR_IF([[mhd_cv_headers_useful_features_present]], [["yes"]],
+ [
+ AS_IF([[test "x${mhd_mse_xopen_flags}" = "x"]], [[:]],
+ [
+ AC_CACHE_CHECK([[whether useful system-specific features works with ${mhd_mse_xopen_flags}]],
+ [[mhd_cv_headers_useful_features_works_xopen]], [dnl
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+${mhd_mse_sys_ext_defines}
+${mhd_mse_xopen_defines}
+${mhd_mse_sys_features_src}
+ ]])],
+ [[mhd_cv_headers_useful_features_works_xopen="yes"]],
+ [[mhd_cv_headers_useful_features_works_xopen="no"]]
+ )dnl
+ ])dnl
+ ]
+ )dnl
+ ]
+ )
+
+
+ AS_IF([[test "x${mhd_cv_headers_useful_features_present}" = "xyes" && \
+ test "x${mhd_cv_headers_useful_features_works_xopen}" = "xno" && \
+ test "x${mhd_mse_xopen_flags}" != "x"]],
+ [
+ _MHD_VAR_CONTAIN([[mhd_mse_xopen_features]], [[, activated by _XOPEN_SOURCE]],
+ [
+ AC_MSG_WARN([[_XOPEN_SOURCE macro is required to activate all headers symbols, however some useful system-specific features does not work with _XOPEN_SOURCE. ]dnl
+ [_XOPEN_SOURCE macro will not be used.]])
+ ]
+ )
+ AS_UNSET([[mhd_mse_xopen_defines]])
+ AS_UNSET([[mhd_mse_xopen_flags]])
+ AS_UNSET([[mhd_mse_xopen_values]])
+ ]
+ )
+
+ dnl Discard temporal source variables
+ AS_UNSET([[mhd_mse_sys_features_src]])
+ AS_UNSET([[mhd_mse_xopen_defines]])
+ AS_UNSET([[mhd_mse_sys_ext_defines]])
- dnl Discard temporal prolog with set of defines.
- AS_UNSET([[mhd_mse_added_prolog]])
dnl Determined all required defines.
AC_MSG_CHECKING([[for final set of defined symbols]])
m4_ifblank([$1], [dnl
AH_TEMPLATE([[_XOPEN_SOURCE]], [Define to maximum value supported by system headers])dnl
AH_TEMPLATE([[_XOPEN_SOURCE_EXTENDED]], [Define to 1 if _XOPEN_SOURCE is defined to value less than 500 ]dnl
- [and system headers requre this symbol])dnl
+ [and system headers require this symbol])dnl
AH_TEMPLATE([[_XOPEN_VERSION]], [Define to maximum value supported by system headers if _XOPEN_SOURCE ]dnl
[is defined to value less than 500 and headers do not support _XOPEN_SOURCE_EXTENDED])dnl
AH_TEMPLATE([[_GNU_SOURCE]], [Define to 1 to enable GNU-related header features])dnl
@@ -426,7 +345,7 @@
AH_TEMPLATE([[_TANDEM_SOURCE]], [Define to 1 if it is required by headers to expose additional symbols])dnl
AH_TEMPLATE([[_ALL_SOURCE]], [Define to 1 if it is required by headers to expose additional symbols])dnl
])
- for mhd_mse_Flag in $mhd_mse_added_exts_flags
+ for mhd_mse_Flag in ${mhd_mse_sys_ext_flags} ${mhd_mse_xopen_flags}
do
m4_ifnblank([$1], [dnl
AS_VAR_APPEND([$1],[[" -D$mhd_mse_Flag"]])
@@ -440,30 +359,38 @@
])
])
done
+ AS_UNSET([[mhd_mse_Flag]])
dnl Trim whitespaces
- mhd_mse_result=`echo $mhd_mse_added_exts_flags`
- AC_MSG_RESULT([[$mhd_mse_result]])
+ mhd_mse_result=`echo ${mhd_mse_sys_ext_flags} ${mhd_mse_xopen_flags}`
+ AC_MSG_RESULT([[${mhd_mse_result}]])
AS_UNSET([[mhd_mse_result]])
-
- AS_UNSET([[mhd_mse_added_exts_flags]])
+ AS_UNSET([[mhd_mse_xopen_flags]])
+ AS_UNSET([[mhd_mse_sys_ext_flags]])
AC_LANG_POP([C])
])
#
-# _MHD_SYS_EXT_ADD_FLAG(FLAG, [FLAG-VALUE = 1])
+# _MHD_SYS_EXT_VAR_ADD_FLAG(DEFINES_VAR, FLAGS_VAR,
+# FLAG, [FLAG-VALUE = 1])
#
-# Internal macro, only to be used from MHD_SYS_EXT, _MHD_XOPEN_ADD
+# Internal macro, only to be used from MHD_SYS_EXT, _MHD_XOPEN_VAR_ADD
-m4_define([_MHD_SYS_EXT_ADD_FLAG], [dnl
- m4_ifnblank([$2],[dnl
- mhd_mse_added_exts_flags="$mhd_mse_added_exts_flags m4_normalize($1)=m4_normalize($2)"
- mhd_mse_added_prolog="${mhd_mse_added_prolog}[#define ]m4_normalize($1) m4_normalize($2)
+m4_define([_MHD_SYS_EXT_VAR_ADD_FLAG], [dnl
+ m4_ifnblank([$4],[dnl
+ ]m4_normalize([$1])[="[$]{]m4_normalize([$1])[}[#define ]m4_normalize($3) ]m4_normalize([$4])[
"
+ AS_IF([test "x[$]{]m4_normalize([$2])[}" = "x"],
+ []m4_normalize([$2])[="]m4_normalize([$3])[=]m4_normalize([$4])["],
+ []m4_normalize([$2])[="[$]{]m4_normalize([$2])[} ]m4_normalize([$3])[=]m4_normalize([$4])["]
+ )dnl
], [dnl
- mhd_mse_added_exts_flags="$mhd_mse_added_exts_flags m4_normalize($1)"
- mhd_mse_added_prolog="${mhd_mse_added_prolog}[#define ]m4_normalize($1) 1
+ ]m4_normalize([$1])[="[$]{]m4_normalize([$1])[}[#define ]m4_normalize($3) 1
"
+ AS_IF([test "x[$]{]m4_normalize([$2])[}" = "x"],
+ []m4_normalize([$2])[="]m4_normalize([$3])["],
+ []m4_normalize([$2])[="[$]{]m4_normalize([$2])[} ]m4_normalize([$3])["]
+ )dnl
])dnl
])
@@ -474,41 +401,360 @@
# both IF-EQ and IF-NOT-EQ are empty.
m4_define([_MHD_VAR_IF],[dnl
-m4_ifnblank([$3][$4],[dnl
-m4_ifblank([$4],[AS_VAR_IF([$1],[$2],[$3])],[dnl
-AS_VAR_IF([$1],[$2],[$3],[$4])])])])
+m4_ifnblank([$3$4],[dnl
+AS_VAR_IF([$1],[$2],[$3],[$4])])])
+
+#
+# _MHD_STRING_CONTAIN(VAR, MATCH, [IF-MATCH], [IF-NOT-MATCH])
+#
+
+AC_DEFUN([_MHD_VAR_CONTAIN],[dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+AS_IF([[`echo "${]$1[}" | $FGREP ']$2[' >/dev/null 2>&1`]], [$3], [$4])
+])
+
+#
+# _MHD_STRING_CONTAIN_BRE(VAR, BRE, [IF-MATCH], [IF-NOT-MATCH])
+#
+
+AC_DEFUN([_MHD_VAR_CONTAIN_BRE],[dnl
+AC_REQUIRE([AC_PROG_GREP])dnl
+AS_IF([[`echo "${]$1[}" | $GREP ']$2[' >/dev/null 2>&1`]], [$3], [$4])
+])
+
+# SYNOPSIS
+#
+# _MHD_CHECK_POSIX2008(DEFINES_VAR, FLAGS_VAR,
+# [EXT_DEFINES],
+# [ACTION-IF-AVAILABLE],
+# [ACTION-IF-NOT-AVAILABLE])
+#
+#
+AC_DEFUN([_MHD_CHECK_POSIX2008], [dnl
+ AC_CACHE_CHECK([headers for POSIX.1-2008/SUSv4 features],
+ [[mhd_cv_headers_posix2008]], [dnl
+ _MHD_CHECK_POSIX_FEATURES_SINGLE([
+_MHD_BASIC_INCLUDES
+[
+/* Check will be passed if ALL features are available
+ * and failed if ANY feature is not available. */
+int main()
+{
+
+#ifndef stpncpy
+ (void) stpncpy;
+#endif
+#ifndef strnlen
+ (void) strnlen;
+#endif
+
+#if !defined(__NetBSD__) && !defined(__OpenBSD__)
+/* NetBSD and OpenBSD didn't implement wcsnlen() for some reason. */
+#ifndef wcsnlen
+ (void) wcsnlen;
+#endif
+#endif
+
+#ifdef __CYGWIN__
+/* The only depend function on Cygwin, but missing on some other platforms */
+#ifndef strndup
+ (void) strndup;
+#endif
+#endif
+
+#ifndef __sun
+/* illumos forget to uncomment some _XPG7 macros. */
+#ifndef renameat
+ (void) renameat;
+#endif
+
+#ifndef getline
+ (void) getline;
+#endif
+#endif /* ! __sun */
+
+/* gmtime_r() becomes mandatory only in POSIX.1-2008. */
+#ifndef gmtime_r
+ (void) gmtime_r;
+#endif
+
+/* unsetenv() actually defined in POSIX.1-2001 so it
+ * must be present with _XOPEN_SOURCE == 700 too. */
+#ifndef unsetenv
+ (void) unsetenv;
+#endif
+
+ return 0;
+}
+ ]],
+ [$3], [[700]],
+ [[mhd_cv_headers_posix2008]]dnl
+ )
+ ]
+ )
+ _MHD_VAR_CONTAIN_BRE([[mhd_cv_headers_posix2008]], [[^available]],
+ [
+ _MHD_VAR_CONTAIN([[mhd_cv_headers_posix2008]], [[does not work with _XOPEN_SOURCE]], [[:]],
+ [_MHD_SYS_EXT_VAR_ADD_FLAG([$1],[$2],[[_XOPEN_SOURCE]],[[700]])]
+ )
+ $4
+ ],
+ [$5]
+ )
+])
+
+
+# SYNOPSIS
+#
+# _MHD_CHECK_POSIX2001(DEFINES_VAR, FLAGS_VAR,
+# [EXT_DEFINES],
+# [ACTION-IF-AVAILABLE],
+# [ACTION-IF-NOT-AVAILABLE])
+#
+#
+AC_DEFUN([_MHD_CHECK_POSIX2001], [dnl
+ AC_CACHE_CHECK([headers for POSIX.1-2001/SUSv3 features],
+ [[mhd_cv_headers_posix2001]], [
+ _MHD_CHECK_POSIX_FEATURES_SINGLE([
+_MHD_BASIC_INCLUDES
+[
+/* Check will be passed if ALL features are available
+ * and failed if ANY feature is not available. */
+int main()
+{
+
+#ifndef setenv
+ (void) setenv;
+#endif
+
+#ifndef __NetBSD__
+#ifndef vsscanf
+ (void) vsscanf;
+#endif
+#endif
+
+/* Availability of next features varies, but they all must be present
+ * on platform with support for _XOPEN_SOURCE = 600. */
+
+/* vsnprintf() should be available with _XOPEN_SOURCE >= 500, but some platforms
+ * provide it only with _POSIX_C_SOURCE >= 200112 (autodefined when
+ * _XOPEN_SOURCE >= 600) where specification of vsnprintf() is aligned with
+ * ISO C99 while others platforms defined it with even earlier standards. */
+#ifndef vsnprintf
+ (void) vsnprintf;
+#endif
+
+/* On platforms that prefer POSIX over X/Open, fseeko() is available
+ * with _POSIX_C_SOURCE >= 200112 (autodefined when _XOPEN_SOURCE >= 600).
+ * On other platforms it should be available with _XOPEN_SOURCE >= 500. */
+#ifndef fseeko
+ (void) fseeko;
+#endif
+
+/* F_GETOWN must be defined with _XOPEN_SOURCE >= 600, but some platforms
+ * define it with _XOPEN_SOURCE >= 500. */
+#ifndef F_GETOWN
+#error F_GETOWN is not defined
+choke me now;
+#endif
+ return 0;
+}
+ ]],
+ [$3],[[600]],[[mhd_cv_headers_posix2001]]dnl
+ )
+ ]
+ )
+ _MHD_VAR_CONTAIN_BRE([[mhd_cv_headers_posix2001]], [[^available]],
+ [
+ _MHD_VAR_CONTAIN([[mhd_cv_headers_posix2001]], [[does not work with _XOPEN_SOURCE]], [[:]],
+ [_MHD_SYS_EXT_VAR_ADD_FLAG([$1],[$2],[[_XOPEN_SOURCE]],[[600]])]
+ )
+ $4
+ ],
+ [$5]
+ )
+])
+
+
+# SYNOPSIS
+#
+# _MHD_CHECK_SUSV2(DEFINES_VAR, FLAGS_VAR,
+# [EXT_DEFINES],
+# [ACTION-IF-AVAILABLE],
+# [ACTION-IF-NOT-AVAILABLE])
+#
+#
+AC_DEFUN([_MHD_CHECK_SUSV2], [dnl
+ AC_CACHE_CHECK([headers for SUSv2/XPG5 features],
+ [[mhd_cv_headers_susv2]], [
+ _MHD_CHECK_POSIX_FEATURES_SINGLE([
+_MHD_BASIC_INCLUDES
+[
+/* Check will be passed if ALL features are available
+ * and failed if ANY feature is not available. */
+int main()
+{
+/* It's not easy to write reliable test for _XOPEN_SOURCE = 500 as
+ * platforms not always precisely follow this standard and some
+ * functions are already deprecated in later standards. */
+
+/* Availability of next features varies, but they all must be present
+ * on platform with correct support for _XOPEN_SOURCE = 500. */
+
+/* Mandatory with _XOPEN_SOURCE >= 500 but as XSI extension available
+ * with much older standards. */
+#ifndef ftruncate
+ (void) ftruncate;
+#endif
+
+/* Added with _XOPEN_SOURCE >= 500 but was available in some standards
+ * before. XSI extension. */
+#ifndef pread
+ (void) pread;
+#endif
+
+#ifndef __APPLE__
+/* Actually comes from XPG4v2 and must be available
+ * with _XOPEN_SOURCE >= 500 as well. */
+#ifndef symlink
+ (void) symlink;
+#endif
+
+/* Actually comes from XPG4v2 and must be available
+ * with _XOPEN_SOURCE >= 500 as well. XSI extension. */
+#ifndef strdup
+ (void) strdup;
+#endif
+#endif /* ! __APPLE__ */
+ return 0;
+}
+ ]],
+ [$3],[[500]],[[mhd_cv_headers_susv2]]dnl
+ )
+ ]
+ )
+ _MHD_VAR_CONTAIN_BRE([[mhd_cv_headers_susv2]], [[^available]],
+ [
+ _MHD_VAR_CONTAIN([[mhd_cv_headers_susv2]], [[does not work with _XOPEN_SOURCE]], [[:]],
+ [_MHD_SYS_EXT_VAR_ADD_FLAG([$1],[$2],[[_XOPEN_SOURCE]],[[500]])]
+ )
+ $4
+ ],
+ [$5]
+ )
+])
+
# SYNOPSIS
#
-# _MHD_CHECK_XOPEN_ENABLE(_XOPEN_SOURCE-VALUE, FEATURES_TEST,
-# [ACTION-IF-ENABLED-BY-XOPEN_SOURCE],
-# [ACTION-IF-NOT],
-# [ACTION-IF-FEATURES-AVALABLE],
-# [ACTION-IF-FEATURES-NOT-AVALABLE],
-# [ACTION-IF-ONLY-WITH-EXTENSIONS]
-# [ACTION-IF-WITHOUT-ALL])
-#
-# DESCRIPTION
-#
-# This macro determines whether the _XOPEN_SOURCE with
-# _XOPEN_SOURCE-VALUE really enable some header features. FEATURES_TEST
-# must contains required includes and main function.
-# One of ACTION-IF-ENABLED-BY-XOPEN_SOURCE and ACTION-IF-NOT
-# is always executed depending on test results.
-# One of ACTION-IF-FEATURES-AVALABLE and is ACTION-IF-FEATURES-NOT-AVALABLE
-# is executed if features can be enabled by _XOPEN_SOURCE, by currently
-# defined (by compiler flags or by predefined macros) extensions or
-# all checked combinations are failed to enable features.
-# ACTION-IF-ONLY-WITH-EXTENSIONS is executed if features can be
-# enabled with not undefined extension.
-# ACTION-IF-WITHOUT-ALL is executed if features work with all
-# disabled extensions (including _XOPEN_SOURCE).
+# _MHD_CHECK_POSIX_FEATURES_SINGLE(FEATURES_TEST,
+# EXT_DEFINES,
+# _XOPEN_SOURCE-VALUE,
+# VAR-RESULT)
+
+AC_DEFUN([_MHD_CHECK_POSIX_FEATURES_SINGLE], [dnl
+ AS_VAR_PUSHDEF([avail_Var], [mhd_cpsxfs_tmp_features_available])dnl
+ AS_VAR_PUSHDEF([ext_Var], [mhd_cpsxfs_tmp_extentions_allowed])dnl
+ AS_VAR_PUSHDEF([xopen_Var], [mhd_cpsxfs_tmp_src_xopen_allowed])dnl
+ AS_VAR_PUSHDEF([dislb_Var], [mhd_cpsxfs_tmp_features_disableable])dnl
+ AS_UNSET([avail_Var])
+ AS_UNSET([ext_Var])
+ AS_UNSET([xopen_Var])
+ AS_UNSET([dislb_Var])
+ _MHD_CHECK_POSIX_FEATURES([$1], [$2], [$3], [avail_Var], [ext_Var], [xopen_Var], [dislb_Var])
+ AS_VAR_IF([avail_Var], ["yes"],
+ [
+ AS_VAR_IF([dislb_Var], ["yes"],
+ [
+ AS_VAR_IF([ext_Var], ["required"],
+ [
+ AS_VAR_IF([xopen_Var], ["allowed"],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, activated by extension macro, works with _XOPEN_SOURCE=]m4_normalize([$3])["])
+ ],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, activated by extension macro, does not work with _XOPEN_SOURCE=]m4_normalize([$3])["])
+ ]
+ )
+ ],
+ [
+ AS_VAR_IF([ext_Var], ["allowed"],
+ [
+ AS_VAR_IF([xopen_Var], ["required"],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, activated by _XOPEN_SOURCE=]m4_normalize([$3])[, works with extension macro"])
+ ],
+ [
+ AS_VAR_IF([xopen_Var], ["allowed"],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, works with _XOPEN_SOURCE=]m4_normalize([$3])[, works with extension macro"])
+ ],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, works with extension macro, does not work with _XOPEN_SOURCE=]m4_normalize([$3])["])
+ ]
+ )
+ ]
+ )
+ ],
+ [
+ AS_VAR_IF([xopen_Var], ["required"],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, activated by _XOPEN_SOURCE=]m4_normalize([$3])[, does not work with extension macro"])
+ ],
+ [
+ AS_VAR_IF([xopen_Var], ["allowed"],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, works with _XOPEN_SOURCE=]m4_normalize([$3])[, does not work with extension macro"])
+ ],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, does not work with _XOPEN_SOURCE=]m4_normalize([$3])[, does not work with extension macro"])
+ ]
+ )
+ ]
+ )
+ ]
+ )
+ ]
+ )
+ ],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["available, works always"])
+ ]
+ )
+ ],
+ [
+ AS_VAR_SET(m4_normalize([$4]), ["not available"])
+ ]
+ )
+ AS_UNSET([dislb_Var])
+ AS_UNSET([xopen_Var])
+ AS_UNSET([ext_Var])
+ AS_UNSET([avail_Var])
+ AS_VAR_POPDEF([dislb_Var])dnl
+ AS_VAR_POPDEF([xopen_Var])dnl
+ AS_VAR_POPDEF([ext_Var])dnl
+ AS_VAR_POPDEF([avail_Var])dnl
+])
-AC_DEFUN([_MHD_CHECK_XOPEN_ENABLE], [dnl
- AS_VAR_PUSHDEF([src_Var], [[mhd_cxoe_tmp_src_variable]])dnl
+# SYNOPSIS
+#
+# _MHD_CHECK_POSIX_FEATURES(FEATURES_TEST, EXT_DEFINES, _XOPEN_SOURCE-VALUE,
+# [VAR-FEATURES-AVAILABLE-YES_NO],
+# [VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED],
+# [VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED],
+# [VAR-FEATURES-DISABLEABLE-YES_NO])
+
+AC_DEFUN([_MHD_CHECK_POSIX_FEATURES], [dnl
+ AS_VAR_PUSHDEF([src_Var], [mhd_cpsxf_tmp_src_variable])dnl
+ AS_VAR_PUSHDEF([defs_Var], [mhd_cpsxf_tmp_defs_variable])dnl
AS_VAR_SET([src_Var],["
+$1
+"])
+ dnl To reduce 'configure' size
+ AS_VAR_SET([defs_Var],["
$2
-"])dnl Reduce 'configure' size
+"])
+ dnl To reduce 'configure' size
dnl Some platforms enable most features when no
dnl specific mode is requested by macro.
@@ -519,171 +765,191 @@
_MHD_UNDEF_ALL_EXT
$src_Var
])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and without _XOPEN_SOURCE]])
- dnl Checked features is enabled in platform's "default" mode.
- dnl Try to disable features by requesting oldest X/Open mode.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _XOPEN_SOURCE 1]
-$src_Var
- ])],
[dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _XOPEN_SOURCE=1]])
- dnl Features still work in oldest X/Open mode.
- dnl Some platforms enable all XSI features for any _XOPEN_SOURCE value.
- dnl Apply some fuzzy logic, try to use _POSIX_C_SOURCE with oldest number.
+ _AS_ECHO_LOG([[Checked features work with undefined all extensions and without _XOPEN_SOURCE]])
+ AS_VAR_SET(m4_normalize([$4]),["yes"]) # VAR-FEATURES-AVAILABLE-YES_NO
+
+ dnl Check whether features will work extensions
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _POSIX_C_SOURCE 1]
+$defs_Var
$src_Var
])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _POSIX_C_SOURCE=1]])
- dnl Features still work in oldest _POSIX_C_SOURCE mode.
- dnl Try to disable features by requesting strict ANSI C mode.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _ANSI_SOURCE 1]
-$src_Var
- ])],
[dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _ANSI_SOURCE]])
- dnl Features still work in strict _ANSI_SOURCE mode.
- dnl Assume that _XOPEN_SOURCE, _POSIX_C_SOURCE and _ANSI_SOURCE has no influence on
- dnl enabling of features as features are enabled always unconditionally.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _ANSI_SOURCE]])
- dnl Features do not work in strict _ANSI_SOURCE mode.
- dnl Try to enable features by _XOPEN_SOURCE with specified value.
+ _AS_ECHO_LOG([[Checked features work with extensions]])
+ AS_VAR_SET(m4_normalize([$5]),["allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ dnl Check whether features will work with _XOPEN_SOURCE
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _ANSI_SOURCE 1]
-[#define _XOPEN_SOURCE] $1
+$defs_Var
+[#define _XOPEN_SOURCE ]]m4_normalize([$3])[
$src_Var
])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _ANSI_SOURCE and _XOPEN_SOURCE=]$1])
- dnl Finally, features were disabled by strict ANSI mode and enabled by adding _XOPEN_SOURCE.
- dnl Assume that _XOPEN_SOURCE can enable features.
- m4_n([$3])dnl ACTION-IF-ENABLED-BY-XOPEN_SOURCE
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _ANSI_SOURCE and _XOPEN_SOURCE=]$1])
- dnl Features are not enabled in strict ANSI mode with _XOPEN_SOURCE.
- dnl Actually this is not correct documented situation and _ANSI_SOURCE may have
- dnl priority over _XOPEN_SOURCE or headers are not controlled by _XOPEN_SOURCE at all.
- dnl As features work in all mode except strict ANSI regardless of _XOPEN_SOURCE,
- dnl assume that _XOPEN_SOURCE do not control visibility of features.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- ])
- ])
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _POSIX_C_SOURCE=1]])
- dnl Features do not work in oldest _POSIX_C_SOURCE mode.
- dnl OK, features were disabled by _POSIX_C_SOURCE.
- dnl Check whether headers controlled by _XOPEN_SOURCE too.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+ [dnl
+ _AS_ECHO_LOG([Checked features work with extensions and with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$6]),["allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ dnl Check whether features could be disabled
+ dnl Request oldest POSIX mode and strict ANSI mode
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
_MHD_UNDEF_ALL_EXT
[#define _POSIX_C_SOURCE 1]
-[#define _XOPEN_SOURCE] $1
+[#define _ANSI_SOURCE 1]
$src_Var
- ])],
+ ])],
+ [dnl
+ _AS_ECHO_LOG([[Checked features work with disabled extensions, with _POSIX_C_SOURCE=1 and _ANSI_SOURCE=1]])
+ AS_VAR_SET(m4_normalize([$7]),["no"]) # VAR-FEATURES-DISABLEABLE-YES_NO
+ ],
+ [dnl
+ _AS_ECHO_LOG([[Checked features DO NOT work with disabled extensions, with _POSIX_C_SOURCE=1 and _ANSI_SOURCE=1]])
+ AS_VAR_SET(m4_normalize([$7]),["yes"]) # VAR-FEATURES-DISABLEABLE-YES_NO
+ ]
+ )
+ ],
+ [dnl
+ _AS_ECHO_LOG([Checked features DO NOT work with extensions and with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$6]),["not allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ AS_VAR_SET(m4_normalize([$7]),["yes"]) # VAR-FEATURES-DISABLEABLE-YES_NO
+ ]
+ )
+ ],
[dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _POSIX_C_SOURCE=1 and _XOPEN_SOURCE=]$1])
- dnl Features were enabled again after adding _XOPEN_SOURCE with value.
- dnl Assume that headers can be controlled by _XOPEN_SOURCE with specified value.
- m4_n([$3])dnl ACTION-IF-ENABLED-BY-XOPEN_SOURCE
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _POSIX_C_SOURCE=1 and _XOPEN_SOURCE=]$1])
- dnl Features still work after adding _XOPEN_SOURCE with value.
- dnl It's unclear whether headers know only about _POSIX_C_SOURCE or
- dnl _POSIX_C_SOURCE have priority over _XOPEN_SOURCE (standards are
- dnl silent about priorities).
- dnl Assume that it's unknown whether _XOPEN_SOURCE can turn on features.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- ])
- ])
- ], [dnl
- _AS_ECHO_LOG([[Checked features does not work with undefined all extensions and with _XOPEN_SOURCE=1]])
- dnl Features disabled by oldest X/Open mode.
- dnl Check whether requested _XOPEN_SOURCE value will turn on features.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _XOPEN_SOURCE] $1
+ _AS_ECHO_LOG([[Checked features DO NOT work with extensions]])
+ AS_VAR_SET(m4_normalize([$7]),["yes"]) # VAR-FEATURES-DISABLEABLE-YES_NO
+ dnl Check whether features work with _XOPEN_SOURCE
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+[#define _XOPEN_SOURCE ]m4_normalize($3)
$src_Var
- ])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _XOPEN_SOURCE=]$1])
- dnl Features work with _XOPEN_SOURCE requested value and do not work
- dnl with value 1.
- dnl Assume that _XOPEN_SOURCE really turn on features.
- m4_n([$3])dnl ACTION-IF-ENABLED-BY-XOPEN_SOURCE
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _XOPEN_SOURCE=]$1])
- dnl Features do not work with _XOPEN_SOURCE, but work in "default" mode.
- dnl Assume that features cannot be enabled by requested _XOPEN_SOURCE value.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- ])
- ])
- m4_n([$5])dnl ACTION-IF-FEATURES-AVALABLE
- m4_n([$8])dnl ACTION-IF-WITHOUT-ALL
- ],
- [dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and without _XOPEN_SOURCE]])
- dnl Features do not work with turned off extensions.
- dnl Check whether they can be enabled by _XOPEN_SOURCE.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-_MHD_UNDEF_ALL_EXT
-[#define _XOPEN_SOURCE] $1
+ ])],
+ [dnl
+ _AS_ECHO_LOG([Checked features work with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ dnl Check default state (without enabling/disabling)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
$src_Var
- ])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with undefined all extensions and with _XOPEN_SOURCE=]$1])
- dnl Features work with _XOPEN_SOURCE and do not work without _XOPEN_SOURCE.
- dnl Assume that _XOPEN_SOURCE really turn on features.
- m4_n([$3])dnl ACTION-IF-ENABLED-BY-XOPEN_SOURCE
- m4_n([$5])dnl ACTION-IF-FEATURES-AVALABLE
+ ])],
+ [dnl
+ _AS_ECHO_LOG([[Checked features work by default]])
+ AS_VAR_SET(m4_normalize([$6]),["allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([[Checked features DO NOT by default]])
+ AS_VAR_SET(m4_normalize([$6]),["required"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ dnl Check whether features work with _XOPEN_SOURCE and extensions
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+$defs_Var
+[#define _XOPEN_SOURCE] ]m4_normalize([$3])[
+$src_Var
+ ])],
+ [dnl
+ _AS_ECHO_LOG([[Checked features work with _XOPEN_SOURCE and extensions]])
+ AS_VAR_SET(m4_normalize([$5]),["allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([[Checked features DO NOT work with _XOPEN_SOURCE and extensions]])
+ AS_VAR_SET(m4_normalize([$5]),["not allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ ],
+ [dnl
+ _AS_ECHO_LOG([Checked features DO NOT work with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$5]),["not allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ AS_VAR_SET(m4_normalize([$6]),["not allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ ]
+ )
],
[dnl
- _AS_ECHO_LOG([[Checked features do not work with undefined all extensions and with _XOPEN_SOURCE=]$1])
- dnl Features do not work with _XOPEN_SOURCE and turned off extensions.
- dnl Retry without turning off known extensions.
+ _AS_ECHO_LOG([[Checked features DO NOT work with undefined all extensions and without _XOPEN_SOURCE]])
+ dnl Let's find the way to enable POSIX features
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-[#define _XOPEN_SOURCE] $1
+$defs_Var
$src_Var
])],
- [dnl
- _AS_ECHO_LOG([[Checked features work with current extensions and with _XOPEN_SOURCE=]$1])
- dnl Features work with _XOPEN_SOURCE and without turning off extensions.
- dnl Check whether features work with oldest _XOPEN_SOURCE or it was enabled only by extensions.
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-[#define _XOPEN_SOURCE 1]
+ [dnl
+ _AS_ECHO_LOG([[Checked features work with extensions]])
+ AS_VAR_SET(m4_normalize([$4]),["yes"]) # VAR-FEATURES-AVAILABLE-YES_NO
+ AS_VAR_SET(m4_normalize([$7]),["yes"]) # VAR-FEATURES-DISABLEABLE-YES_NO
+ dnl Check default state (without enabling/disabling)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+$src_Var
+ ])],
+ [dnl
+ _AS_ECHO_LOG([[Checked features work by default]])
+ AS_VAR_SET(m4_normalize([$5]),["allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([[Checked features DO NOT by default]])
+ AS_VAR_SET(m4_normalize([$5]),["required"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ dnl Check whether features work with extensions and _XOPEN_SOURCE
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+$defs_Var
+[#define _XOPEN_SOURCE] ]m4_normalize([$3])[
$src_Var
- ])],
+ ])],
+ [dnl
+ _AS_ECHO_LOG([Checked features work with extensions and _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$6]),["allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([Checked features DO NOT work with extensions and _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$6]),["not allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ ],
[dnl
- _AS_ECHO_LOG([[Checked features work with current extensions and with _XOPEN_SOURCE=1]])
- dnl Features still work with oldest _XOPEN_SOURCE.
- dnl Assume that _XOPEN_SOURCE has no influence on enabling of features.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with current extensions and with _XOPEN_SOURCE=1]])
- dnl Features do not work with oldest _XOPEN_SOURCE.
- dnl Assume that _XOPEN_SOURCE really turn on features.
- m4_n([$3])dnl ACTION-IF-ENABLED-BY-XOPEN_SOURCE
- ])
- m4_n([$5])dnl ACTION-IF-FEATURES-AVALABLE
- m4_n([$7])dnl ACTION-IF-ONLY-WITH-EXTENSIONS
- ], [dnl
- _AS_ECHO_LOG([[Checked features do not work with current extensions and with _XOPEN_SOURCE=]$1])
- dnl Features do not work in all checked conditions.
- dnl Assume that _XOPEN_SOURCE cannot enable feature.
- m4_n([$4])dnl ACTION-IF-NOT-ENABLED-BY-XOPEN_SOURCE
- m4_n([$6])dnl ACTION-IF-FEATURE-NOT-AVALABLE
- ])
- ])
- ])
+ _AS_ECHO_LOG([[Checked features DO NOT work with extensions]])
+ dnl Check whether features work with _XOPEN_SOURCE
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+[#define _XOPEN_SOURCE] ]m4_normalize([$3])[
+$src_Var
+ ])],
+ [dnl
+ _AS_ECHO_LOG([Checked features work with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$4]),["yes"]) # VAR-FEATURES-AVAILABLE-YES_NO
+ dnl Check default state (without enabling/disabling)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+$src_Var
+ ])],
+ [dnl
+ _AS_ECHO_LOG([[Checked features work by default]])
+ AS_VAR_SET(m4_normalize([$6]),["allowed"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([[Checked features DO NOT by default]])
+ AS_VAR_SET(m4_normalize([$6]),["required"]) # VAR-XOPEN-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ dnl Check whether features work with _XOPEN_SOURCE and extensions
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+$defs_Var
+[#define _XOPEN_SOURCE] ]m4_normalize([$3])[
+$src_Var
+ ])],
+ [dnl
+ _AS_ECHO_LOG([Checked features work with _XOPEN_SOURCE=]m4_normalize([$3])[ and extensions])
+ AS_VAR_SET(m4_normalize([$5]),["allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ],
+ [dnl
+ _AS_ECHO_LOG([Checked features DO NOT work with _XOPEN_SOURCE=]m4_normalize([$3])[ and extensions])
+ AS_VAR_SET(m4_normalize([$5]),["not allowed"]) # VAR-EXTENSIONS-REQUIRED_NOT-ALLOWED_ALLOWED
+ ]
+ )
+ ],
+ [dnl
+ _AS_ECHO_LOG([Checked features DO NOT work with _XOPEN_SOURCE=]m4_normalize([$3])[])
+ AS_VAR_SET(m4_normalize([$4]),["no"]) # VAR-FEATURES-AVAILABLE-YES_NO
+ ]
+ )
+ ]
+ )
+ ]
+ )
+ AS_UNSET([defs_Var])
AS_UNSET([src_Var])
+ AS_VAR_POPDEF([defs_Var])dnl
AS_VAR_POPDEF([src_Var])dnl
])
@@ -828,7 +1094,7 @@
AC_COMPILE_IFELSE([dnl
AC_LANG_PROGRAM([m4_n([$1])dnl
_MHD_BASIC_INCLUDES
- ], [[int i = 1; i++]])
+ ], [[int i = 1; i++; if(i) return i]])
], [$2], [$3])
])
@@ -914,7 +1180,7 @@
choke me now;
#endif
]],[])
- ], [$3], [$4]
+ ], [m4_default_nblank([$3])], [m4_default_nblank([$4])]
)
])
@@ -927,13 +1193,11 @@
# Cache-check for defined symbols with printing results.
AC_DEFUN([MHD_CHECK_DEFINED], [dnl
- AS_VAR_PUSHDEF([mhd_cache_Var],
- [mhd_cv_macro_[]m4_tolower($1)_defined])dnl
+ AS_VAR_PUSHDEF([mhd_cache_Var],[mhd_cv_macro_[]m4_tolower(m4_normalize($1))_defined])dnl
AC_CACHE_CHECK([dnl
-m4_ifnblank([$5], [$5], [whether $1 is already defined])],
- [mhd_cache_Var],
- [
- _MHD_CHECK_DEFINED([$1], [$2],
+m4_ifnblank([$5], [$5], [whether ]m4_normalize([$1])[ is already defined])],
+ [mhd_cache_Var], [dnl
+ _MHD_CHECK_DEFINED(m4_normalize([$1]), [$2],
[mhd_cache_Var="yes"],
[mhd_cache_Var="no"]
)
@@ -963,12 +1227,12 @@
AC_DEFUN([MHD_CHECK_ACCEPT_DEFINE], [dnl
AC_PREREQ([2.64])dnl for AS_VAR_PUSHDEF, AS_VAR_SET, m4_ifnblank
AS_VAR_PUSHDEF([mhd_cache_Var],
- [mhd_cv_define_[]m4_tolower($1)_accepted[]m4_ifnblank([$2],[_[]$2])])dnl
+ [mhd_cv_define_[]m4_tolower(m4_normalize($1))[]_accepted[]m4_ifnblank([$2],[_[]$2])])dnl
AC_CACHE_CHECK([dnl
-m4_ifnblank([$6],[$6],[whether headers accept $1[]m4_ifnblank([$2],[ with value $2])])],
+m4_ifnblank([$6],[$6],[whether headers accept $1[]m4_ifnblank([$2],[[ with value ]$2])])],
[mhd_cache_Var], [dnl
MHD_CHECK_BASIC_HEADERS([
-m4_n([$3])[#define ]$1 m4_default_nblank([$2],[[1]])],
+m4_n([$3])[#define ]$1 m4_default_nblank($2,[[1]])],
[mhd_cache_Var="yes"], [mhd_cache_Var="no"]
)
])
@@ -992,44 +1256,69 @@
])dnl
])
-
#
-# _MHD_XOPEN_ADD([PROLOG])
+# _MHD_XOPEN_VAR_ADD(DEFINES_VAR, FLAGS_VAR, [PROLOG])
#
# Internal macro. Only to be used in MHD_SYS_EXT.
-AC_DEFUN([_MHD_XOPEN_ADD], [dnl
- MHD_CHECK_DEF_AND_ACCEPT([[_XOPEN_SOURCE_EXTENDED]], [],
- [[${mhd_mse_added_prolog}]m4_n([$1])], [],
- [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_SOURCE_EXTENDED]])dnl
- ], [dnl
- MHD_CHECK_DEFINED([[_XOPEN_VERSION]],
- [[${mhd_mse_added_prolog}]m4_n([$1])], [],
- [dnl
- AC_CACHE_CHECK([[for value of _XOPEN_VERSION accepted by headers]],
- [mhd_cv_define__xopen_version_accepted], [dnl
- MHD_CHECK_BASIC_HEADERS([
-[${mhd_mse_added_prolog}]m4_n([$1])
-[#define _XOPEN_VERSION 4]],
- [[mhd_cv_define__xopen_version_accepted="4"]],
+AC_DEFUN([_MHD_XOPEN_VAR_ADD], [dnl
+ MHD_CHECK_DEF_AND_ACCEPT([[_XOPEN_SOURCE]], [[1]], [$3],
+ [
+ AC_CACHE_CHECK([[whether predefined value of _XOPEN_SOURCE is more or equal 500]],
+ [[mhd_cv_macro__xopen_source_def_fiveh]], [dnl
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+m4_n([$3])dnl
+[#if _XOPEN_SOURCE+0 < 500
+#error Value of _XOPEN_SOURCE is less than 500
+choke me now;
+#endif
+ ]],[[int i = 0; i++; if(i) return i]])],
+ [[mhd_cv_macro__xopen_source_def_fiveh="yes"]],
+ [[mhd_cv_macro__xopen_source_def_fiveh="no"]]
+ )dnl
+ ]
+ )dnl
+ ],
+ [_MHD_SYS_EXT_VAR_ADD_FLAG([$1], [$2], [[_XOPEN_SOURCE]], [[1]])]
+ )
+ AS_IF([[test "x${mhd_cv_define__xopen_source_accepted_1}" = "xyes" || \
+ test "x${mhd_cv_macro__xopen_source_def_fiveh}" = "xno"]],
+ [
+ MHD_CHECK_DEF_AND_ACCEPT([[_XOPEN_SOURCE_EXTENDED]], [],
[
- MHD_CHECK_BASIC_HEADERS([
-[${mhd_mse_added_prolog}]m4_n([$1])
+m4_n([$3])], [],
+ [dnl
+ _MHD_SYS_EXT_VAR_ADD_FLAG([$1],[$2],[[_XOPEN_SOURCE_EXTENDED]])
+ ], [dnl
+ MHD_CHECK_DEFINED([[_XOPEN_VERSION]],
+ [
+m4_n([$3])], [],
+ [dnl
+ AC_CACHE_CHECK([[for value of _XOPEN_VERSION accepted by headers]],
+ [mhd_cv_define__xopen_version_accepted], [dnl
+ MHD_CHECK_BASIC_HEADERS([
+m4_n([$3])
+[#define _XOPEN_VERSION 4]],
+ [[mhd_cv_define__xopen_version_accepted="4"]],
+ [
+ MHD_CHECK_BASIC_HEADERS([
+m4_n([$3])
[#define _XOPEN_VERSION 3]],
- [[mhd_cv_define__xopen_version_accepted="3"]],
- [[mhd_cv_define__xopen_version_accepted="no"]]
- )
+ [[mhd_cv_define__xopen_version_accepted="3"]],
+ [[mhd_cv_define__xopen_version_accepted="no"]]
+ )
+ ])
+ ])
+ AS_VAR_IF([mhd_cv_define__xopen_version_accepted], [["no"]],
+ [[:]],
+ [dnl
+ _MHD_SYS_EXT_VAR_ADD_FLAG([$1],[$2],[[_XOPEN_VERSION]],
+ [[${mhd_cv_define__xopen_version_accepted}]]dnl
+ )
+ ])
])
])
- AS_VAR_IF([mhd_cv_define__xopen_version_accepted], [["no"]],
- [[:]],
- [dnl
- _MHD_SYS_EXT_ADD_FLAG([[_XOPEN_VERSION]],
- [[${mhd_cv_define__xopen_version_accepted}]]dnl
- )
- ])
- ])
- ])
+ ]
+ )dnl
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/nls.m4
^
|
@@ -1,16 +1,16 @@
-# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016 Free Software
-dnl Foundation, Inc.
+# nls.m4 serial 6 (gettext-0.20.2)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2021 Free
+dnl Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/pkg.m4
^
|
@@ -86,7 +86,7 @@
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-dnl only at the first occurence in configure.ac, so if the first place
+dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/po.m4
^
|
@@ -1,15 +1,15 @@
-# po.m4 serial 24 (gettext-0.19)
-dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
+# po.m4 serial 31 (gettext-0.20.2)
+dnl Copyright (C) 1995-2014, 2016, 2018-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
@@ -30,7 +30,7 @@
dnl Release version of the gettext macros. This is used to ensure that
dnl the gettext macros and po/Makefile.in.in are in sync.
- AC_SUBST([GETTEXT_MACRO_VERSION], [0.19])
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.20])
dnl Perform the following tests also if --disable-nls has been given,
dnl because they are needed for "make dist" to work.
@@ -46,13 +46,6 @@
dnl Test whether it is GNU msgfmt >= 0.15.
changequote(,)dnl
- case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
- *) MSGFMT_015=$MSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([MSGFMT_015])
-changequote(,)dnl
case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
'' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
*) GMSGFMT_015=$GMSGFMT ;;
@@ -83,11 +76,21 @@
AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
[$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
- dnl Installation directories.
- dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
- dnl have to define it here, so that it can be used in po/Makefile.
- test -n "$localedir" || localedir='${datadir}/locale'
- AC_SUBST([localedir])
+ dnl Test whether it is GNU msgmerge >= 0.20.
+ if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then
+ MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt'
+ else
+ dnl Test whether it is GNU msgmerge >= 0.12.
+ if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then
+ MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet'
+ else
+ dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is
+ dnl slow. But this is not a big problem, as such old gettext versions are
+ dnl hardly in use any more.
+ MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet'
+ fi
+ fi
+ AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION])
dnl Support for AM_XGETTEXT_OPTION.
test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
@@ -130,14 +133,11 @@
if test -n "$OBSOLETE_ALL_LINGUAS"; then
test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
fi
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
- # Hide the ALL_LINGUAS assignment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
else
# The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assignment from automake < 1.5.
- eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS
fi
# Compute POFILES
# as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
@@ -208,9 +208,8 @@
esac
done]],
[# Capture the value of obsolete ALL_LINGUAS because we need it to compute
- # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
- # from automake < 1.5.
- eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS.
+ OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS"
# Capture the value of LINGUAS because we need it to compute CATALOGS.
LINGUAS="${LINGUAS-%UNSET%}"
])
@@ -311,15 +310,13 @@
fi
if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
# The LINGUAS file contains the set of available languages.
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
else
# Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
- ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+ ALL_LINGUAS=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
fi
- # Hide the ALL_LINGUAS assignment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
# Compute POFILES
# as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
# Compute UPDATEPOFILES
@@ -329,9 +326,9 @@
# Compute GMOFILES
# as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
# Compute PROPERTIESFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).properties)
# Compute CLASSFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).class)
# Compute QMFILES
# as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
# Compute MSGFILES
@@ -356,8 +353,8 @@
UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
- CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+ PROPERTIESFILES="$PROPERTIESFILES \$(srcdir)/\$(DOMAIN)_$lang.properties"
+ CLASSFILES="$CLASSFILES \$(srcdir)/\$(DOMAIN)_$lang.class"
QMFILES="$QMFILES $srcdirpre$lang.qm"
frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/progtest.m4
^
|
@@ -1,22 +1,22 @@
-# progtest.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1996-2003, 2005, 2008-2016 Free Software Foundation, Inc.
+# progtest.m4 serial 9 (gettext-0.21.1)
+dnl Copyright (C) 1996-2003, 2005, 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
+dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
+dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
dnl Ulrich Drepper <drepper@cygnus.com>, 1996.
-AC_PREREQ([2.50])
+AC_PREREQ([2.53])
# Search path for a program which passes the given test.
@@ -61,7 +61,7 @@
;;
*)
ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ for ac_dir in m4_if([$5], , $PATH, [$5]); do
IFS="$ac_save_IFS"
test -z "$ac_dir" && ac_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
@@ -77,12 +77,12 @@
IFS="$ac_save_IFS"
dnl If no 4th arg is given, leave the cache variable unset,
dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+m4_if([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
])dnl
;;
esac])dnl
$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+if test m4_if([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
AC_MSG_RESULT([$][$1])
else
AC_MSG_RESULT([no])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/search_h.m4
^
|
@@ -1,5 +1,5 @@
-# search_h.m4 serial 9
-dnl Copyright (C) 2007-2017 Free Software Foundation, Inc.
+# search_h.m4 serial 12
+dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -40,6 +40,8 @@
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[#include <search.h>
]], [tdelete tfind tsearch twalk])
+
+ AC_REQUIRE([AC_C_RESTRICT])
])
AC_DEFUN([gl_SEARCH_MODULE_INDICATOR],
@@ -54,7 +56,11 @@
AC_DEFUN([gl_SEARCH_H_DEFAULTS],
[
GNULIB_TSEARCH=0; AC_SUBST([GNULIB_TSEARCH])
+ dnl Support Microsoft deprecated alias function names by default.
+ GNULIB_MDA_LFIND=1; AC_SUBST([GNULIB_MDA_LFIND])
+ GNULIB_MDA_LSEARCH=1; AC_SUBST([GNULIB_MDA_LSEARCH])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_TSEARCH=1; AC_SUBST([HAVE_TSEARCH])
+ HAVE_TWALK=1; AC_SUBST([HAVE_TWALK])
REPLACE_TSEARCH=0; AC_SUBST([REPLACE_TSEARCH])
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/size_max.m4
^
|
@@ -1,17 +1,19 @@
-# size_max.m4 serial 10
-dnl Copyright (C) 2003, 2005-2006, 2008-2016 Free Software Foundation, Inc.
+# size_max.m4 serial 12
+dnl Copyright (C) 2003, 2005-2006, 2008-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
+AC_PREREQ([2.61])
+
AC_DEFUN([gl_SIZE_MAX],
[
AC_CHECK_HEADERS([stdint.h])
dnl First test whether the system already has SIZE_MAX.
AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [
- gl_cv_size_max=
+ gl_cv_size_max=no
AC_EGREP_CPP([Found it], [
#include <limits.h>
#if HAVE_STDINT_H
@@ -21,7 +23,7 @@
Found it
#endif
], [gl_cv_size_max=yes])
- if test -z "$gl_cv_size_max"; then
+ if test $gl_cv_size_max != yes; then
dnl Define it ourselves. Here we assume that the type 'size_t' is not wider
dnl than the type 'unsigned long'. Try hard to find a definition that can
dnl be used in a preprocessor #if, i.e. doesn't contain a cast.
@@ -71,9 +73,3 @@
# undef SIZE_MAX
#endif])
])
-
-dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
-dnl Remove this when we can assume autoconf >= 2.61.
-m4_ifdef([AC_COMPUTE_INT], [], [
- AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
-])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/threadlib.m4
^
|
@@ -1,11 +1,351 @@
-# threadlib.m4 serial 11 (gettext-0.18.2)
-dnl Copyright (C) 2005-2016 Free Software Foundation, Inc.
+# threadlib.m4 serial 29
+dnl Copyright (C) 2005-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
+AC_PREREQ([2.60])
+
+dnl The general structure of the multithreading modules in gnulib is that we
+dnl have three set of modules:
+dnl
+dnl * POSIX API:
+dnl pthread, which combines
+dnl pthread-h
+dnl pthread-thread
+dnl pthread-once
+dnl pthread-mutex
+dnl pthread-rwlock
+dnl pthread-cond
+dnl pthread-tss
+dnl pthread-spin
+dnl sched_yield
+dnl
+dnl * ISO C API:
+dnl threads, which combines
+dnl threads-h
+dnl thrd
+dnl mtx
+dnl cnd
+dnl tss
+dnl
+dnl * Gnulib API, with an implementation that can be chosen at configure
+dnl time through the option --enable-threads=...
+dnl thread
+dnl lock
+dnl cond
+dnl tls
+dnl yield
+dnl
+dnl They are independent, except for the fact that
+dnl - the implementation of the ISO C API may use the POSIX (or some other
+dnl platform dependent) API,
+dnl - the implementation of the Gnulib API may use the POSIX or ISO C or
+dnl some other platform dependent API, depending on the --enable-threads
+dnl option.
+dnl
+dnl This file contains macros for all of these APIs!
+
+dnl ============================================================================
+dnl Macros for all thread APIs
+
+AC_DEFUN([gl_ANYTHREADLIB_EARLY],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ if test -z "$gl_anythreadlib_early_done"; then
+ case "$host_os" in
+ osf*)
+ # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
+ # groks <pthread.h>. cc also understands the flag -pthread, but
+ # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
+ # 2. putting a flag into CPPFLAGS that has an effect on the linker
+ # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
+ # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+ ;;
+ esac
+ # Some systems optimize for single-threaded programs by default, and
+ # need special flags to disable these optimizations. For example, the
+ # definition of 'errno' in <errno.h>.
+ case "$host_os" in
+ aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
+ solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
+ esac
+ gl_anythreadlib_early_done=done
+ fi
+])
+
+dnl Checks whether the compiler and linker support weak declarations of symbols.
+
+AC_DEFUN([gl_WEAK_SYMBOLS],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_CACHE_CHECK([whether imported symbols can be declared weak],
+ [gl_cv_have_weak],
+ [gl_cv_have_weak=no
+ dnl First, test whether the compiler accepts it syntactically.
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[extern void xyzzy ();
+#pragma weak xyzzy]],
+ [[xyzzy();]])],
+ [gl_cv_have_weak=maybe])
+ if test $gl_cv_have_weak = maybe; then
+ dnl Second, test whether it actually works. On Cygwin 1.7.2, with
+ dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdio.h>
+#pragma weak fputs
+int main ()
+{
+ return (fputs == NULL);
+}]])],
+ [gl_cv_have_weak=yes],
+ [gl_cv_have_weak=no],
+ [dnl When cross-compiling, assume that only ELF platforms support
+ dnl weak symbols.
+ AC_EGREP_CPP([Extensible Linking Format],
+ [#ifdef __ELF__
+ Extensible Linking Format
+ #endif
+ ],
+ [gl_cv_have_weak="guessing yes"],
+ [gl_cv_have_weak="guessing no"])
+ ])
+ fi
+ dnl But when linking statically, weak symbols don't work.
+ case " $LDFLAGS " in
+ *" -static "*) gl_cv_have_weak=no ;;
+ esac
+ dnl Test for a bug in FreeBSD 11: A link error occurs when using a weak
+ dnl symbol and linking against a shared library that has a dependency on
+ dnl the shared library that defines the symbol.
+ case "$gl_cv_have_weak" in
+ *yes)
+ case "$host_os" in
+ freebsd* | dragonfly*)
+ : > conftest1.c
+ $CC $CPPFLAGS $CFLAGS $LDFLAGS -fPIC -shared -o libempty.so conftest1.c -lpthread >&AS_MESSAGE_LOG_FD 2>&1
+ cat <<EOF > conftest2.c
+#include <pthread.h>
+#pragma weak pthread_mutexattr_gettype
+int main ()
+{
+ return (pthread_mutexattr_gettype != NULL);
+}
+EOF
+ $CC $CPPFLAGS $CFLAGS $LDFLAGS -o conftest conftest2.c libempty.so >&AS_MESSAGE_LOG_FD 2>&1 \
+ || gl_cv_have_weak=no
+ rm -f conftest1.c libempty.so conftest2.c conftest
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ case "$gl_cv_have_weak" in
+ *yes)
+ AC_DEFINE([HAVE_WEAK_SYMBOLS], [1],
+ [Define to 1 if the compiler and linker support weak declarations of symbols.])
+ ;;
+ esac
+])
+
+dnl ============================================================================
+dnl Macros for the POSIX API
+
+dnl gl_PTHREADLIB
+dnl -------------
+dnl Tests for the libraries needs for using the POSIX threads API.
+dnl Sets the variable LIBPTHREAD to the linker options for use in a Makefile.
+dnl Sets the variable LIBPMULTITHREAD, for programs that really need
+dnl multithread functionality. The difference between LIBPTHREAD and
+dnl LIBPMULTITHREAD is that on platforms supporting weak symbols, typically
+dnl LIBPTHREAD is empty whereas LIBPMULTITHREAD is not.
+dnl Sets the variable LIB_SCHED_YIELD to the linker options needed to use the
+dnl sched_yield() function.
+dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
+dnl multithread-safe programs.
+dnl Defines the C macro HAVE_PTHREAD_API if (at least parts of) the POSIX
+dnl threads API is available.
+
+dnl The guts of gl_PTHREADLIB. Needs to be expanded only once.
+
+AC_DEFUN([gl_PTHREADLIB_BODY],
+[
+ AC_REQUIRE([gl_ANYTHREADLIB_EARLY])
+ if test -z "$gl_pthreadlib_body_done"; then
+ gl_pthread_api=no
+ LIBPTHREAD=
+ LIBPMULTITHREAD=
+ # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
+ # it groks <pthread.h>. It's added above, in gl_ANYTHREADLIB_EARLY.
+ AC_CHECK_HEADER([pthread.h],
+ [gl_have_pthread_h=yes], [gl_have_pthread_h=no])
+ if test "$gl_have_pthread_h" = yes; then
+ # Other possible tests:
+ # -lpthreads (FSU threads, PCthreads)
+ # -lgthreads
+ # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
+ # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
+ # the second one only in libpthread, and lock.c needs it.
+ #
+ # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04
+ # needs -pthread for some reason. See:
+ # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html
+ save_LIBS=$LIBS
+ for gl_pthread in '' '-pthread'; do
+ LIBS="$LIBS $gl_pthread"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <pthread.h>
+ pthread_mutex_t m;
+ pthread_mutexattr_t ma;
+ ]],
+ [[pthread_mutex_lock (&m);
+ pthread_mutexattr_init (&ma);]])],
+ [gl_pthread_api=yes
+ LIBPTHREAD=$gl_pthread
+ LIBPMULTITHREAD=$gl_pthread])
+ LIBS=$save_LIBS
+ test $gl_pthread_api = yes && break
+ done
+
+ # Test for libpthread by looking for pthread_kill. (Not pthread_self,
+ # since it is defined as a macro on OSF/1.)
+ if test $gl_pthread_api = yes && test -z "$LIBPTHREAD"; then
+ # The program links fine without libpthread. But it may actually
+ # need to link with libpthread in order to create multiple threads.
+ AC_CHECK_LIB([pthread], [pthread_kill],
+ [LIBPMULTITHREAD=-lpthread
+ # On Solaris and HP-UX, most pthread functions exist also in libc.
+ # Therefore pthread_in_use() needs to actually try to create a
+ # thread: pthread_create from libc will fail, whereas
+ # pthread_create will actually create a thread.
+ # On Solaris 10 or newer, this test is no longer needed, because
+ # libc contains the fully functional pthread functions.
+ case "$host_os" in
+ solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*)
+ AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
+ [Define if the pthread_in_use() detection is hard.])
+ esac
+ ])
+ elif test $gl_pthread_api != yes; then
+ # Some library is needed. Try libpthread and libc_r.
+ AC_CHECK_LIB([pthread], [pthread_kill],
+ [gl_pthread_api=yes
+ LIBPTHREAD=-lpthread
+ LIBPMULTITHREAD=-lpthread])
+ if test $gl_pthread_api != yes; then
+ # For FreeBSD 4.
+ AC_CHECK_LIB([c_r], [pthread_kill],
+ [gl_pthread_api=yes
+ LIBPTHREAD=-lc_r
+ LIBPMULTITHREAD=-lc_r])
+ fi
+ fi
+ fi
+ AC_MSG_CHECKING([whether POSIX threads API is available])
+ AC_MSG_RESULT([$gl_pthread_api])
+ AC_SUBST([LIBPTHREAD])
+ AC_SUBST([LIBPMULTITHREAD])
+ if test $gl_pthread_api = yes; then
+ AC_DEFINE([HAVE_PTHREAD_API], [1],
+ [Define if you have the <pthread.h> header and the POSIX threads API.])
+ fi
+
+ dnl On some systems, sched_yield is in librt, rather than in libpthread.
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sched.h>]],
+ [[sched_yield ();]])],
+ [LIB_SCHED_YIELD=
+ ],
+ [dnl Solaris 7...10 has sched_yield in librt, not in libpthread or libc.
+ AC_CHECK_LIB([rt], [sched_yield], [LIB_SCHED_YIELD=-lrt],
+ [dnl Solaris 2.5.1, 2.6 has sched_yield in libposix4, not librt.
+ AC_CHECK_LIB([posix4], [sched_yield], [LIB_SCHED_YIELD=-lposix4])])
+ ])
+ AC_SUBST([LIB_SCHED_YIELD])
+
+ gl_pthreadlib_body_done=done
+ fi
+])
+
+AC_DEFUN([gl_PTHREADLIB],
+[
+ AC_REQUIRE([gl_ANYTHREADLIB_EARLY])
+ gl_PTHREADLIB_BODY
+])
+
+dnl ============================================================================
+dnl Macros for the ISO C API
+
+dnl gl_STDTHREADLIB
+dnl ---------------
+dnl Tests for the libraries needs for using the ISO C threads API.
+dnl Sets the variable LIBSTDTHREAD to the linker options for use in a Makefile.
+dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
+dnl multithread-safe programs.
+dnl Defines the C macro HAVE_THREADS_H if (at least parts of) the ISO C threads
+dnl API is available.
+
+dnl The guts of gl_STDTHREADLIB. Needs to be expanded only once.
+
+AC_DEFUN([gl_STDTHREADLIB_BODY],
+[
+ AC_REQUIRE([gl_ANYTHREADLIB_EARLY])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ if test -z "$gl_stdthreadlib_body_done"; then
+ AC_CHECK_HEADERS_ONCE([threads.h])
+
+ case "$host_os" in
+ mingw*)
+ LIBSTDTHREAD=
+ ;;
+ *)
+ gl_PTHREADLIB_BODY
+ if test $ac_cv_header_threads_h = yes; then
+ dnl glibc >= 2.29 has thrd_create in libpthread.
+ dnl FreeBSD >= 10 has thrd_create in libstdthreads; this library depends
+ dnl on libpthread (for the symbol 'pthread_mutexattr_gettype').
+ dnl AIX >= 7.1 and Solaris >= 11.4 have thrd_create in libc.
+ AC_CHECK_FUNCS([thrd_create])
+ if test $ac_cv_func_thrd_create = yes; then
+ LIBSTDTHREAD=
+ else
+ AC_CHECK_LIB([stdthreads], [thrd_create], [
+ LIBSTDTHREAD='-lstdthreads -lpthread'
+ ], [
+ dnl Guess that thrd_create is in libpthread.
+ LIBSTDTHREAD="$LIBPMULTITHREAD"
+ ])
+ fi
+ else
+ dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c.
+ LIBSTDTHREAD="$LIBPMULTITHREAD $LIB_SCHED_YIELD"
+ fi
+ ;;
+ esac
+ AC_SUBST([LIBSTDTHREAD])
+
+ AC_MSG_CHECKING([whether ISO C threads API is available])
+ AC_MSG_RESULT([$ac_cv_header_threads_h])
+ gl_stdthreadlib_body_done=done
+ fi
+])
+
+AC_DEFUN([gl_STDTHREADLIB],
+[
+ AC_REQUIRE([gl_ANYTHREADLIB_EARLY])
+ gl_STDTHREADLIB_BODY
+])
+
+dnl ============================================================================
+dnl Macros for the Gnulib API
+
dnl gl_THREADLIB
dnl ------------
dnl Tests for a multithreading library to be used.
@@ -14,8 +354,13 @@
dnl default is 'no', otherwise it is system dependent. In both cases, the user
dnl can change the choice through the options --enable-threads=choice or
dnl --disable-threads.
-dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
-dnl USE_PTH_THREADS, USE_WINDOWS_THREADS
+dnl Defines at most one of the macros USE_ISOC_THREADS, USE_POSIX_THREADS,
+dnl USE_ISOC_AND_POSIX_THREADS, USE_WINDOWS_THREADS.
+dnl The choice --enable-threads=isoc+posix is available only on platforms that
+dnl have both the ISO C and the POSIX threads APIs. It has the effect of using
+dnl the ISO C API for most things and the POSIX API only for creating and
+dnl controlling threads (because there is no equivalent to pthread_atfork in
+dnl the ISO C API).
dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
dnl libtool).
@@ -25,6 +370,9 @@
dnl symbols, typically LIBTHREAD is empty whereas LIBMULTITHREAD is not.
dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
dnl multithread-safe programs.
+dnl Since support for GNU pth was removed, $LTLIBTHREAD and $LIBTHREAD have the
+dnl same value, and similarly $LTLIBMULTITHREAD and $LIBMULTITHREAD have the
+dnl same value. Only system libraries are needed.
AC_DEFUN([gl_THREADLIB_EARLY],
[
@@ -43,18 +391,15 @@
AC_REQUIRE([AC_CANONICAL_HOST])
dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.
- dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
- dnl AC_GNU_SOURCE.
- m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
- [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
- [AC_REQUIRE([AC_GNU_SOURCE])])
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
dnl Check for multithreading.
m4_ifdef([gl_THREADLIB_DEFAULT_NO],
[m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],
[m4_divert_text([DEFAULTS], [gl_use_threads_default=])])
+ m4_divert_text([DEFAULTS], [gl_use_winpthreads_default=])
AC_ARG_ENABLE([threads],
-AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
-AC_HELP_STRING([--disable-threads], [build without multithread safety])]),
+AS_HELP_STRING([--enable-threads={isoc|posix|isoc+posix|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
+AS_HELP_STRING([--disable-threads], [build without multithread safety])]),
[gl_use_threads=$enableval],
[if test -n "$gl_use_threads_default"; then
gl_use_threads="$gl_use_threads_default"
@@ -64,41 +409,35 @@
dnl Disable multithreading by default on OSF/1, because it interferes
dnl with fork()/exec(): When msgexec is linked with -lpthread, its
dnl child process gets an endless segmentation fault inside execvp().
+ osf*) gl_use_threads=no ;;
dnl Disable multithreading by default on Cygwin 1.5.x, because it has
dnl bugs that lead to endless loops or crashes. See
- dnl <http://cygwin.com/ml/cygwin/2009-08/msg00283.html>.
- osf*) gl_use_threads=no ;;
+ dnl <https://cygwin.com/ml/cygwin/2009-08/msg00283.html>.
cygwin*)
case `uname -r` in
1.[0-5].*) gl_use_threads=no ;;
*) gl_use_threads=yes ;;
esac
;;
+ dnl Obey gl_AVOID_WINPTHREAD on mingw.
+ mingw*)
+ case "$gl_use_winpthreads_default" in
+ yes) gl_use_threads=posix ;;
+ no) gl_use_threads=windows ;;
+ *) gl_use_threads=yes ;;
+ esac
+ ;;
*) gl_use_threads=yes ;;
esac
changequote([,])dnl
fi
])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # For using <pthread.h>:
- case "$host_os" in
- osf*)
- # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
- # groks <pthread.h>. cc also understands the flag -pthread, but
- # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
- # 2. putting a flag into CPPFLAGS that has an effect on the linker
- # causes the AC_LINK_IFELSE test below to succeed unexpectedly,
- # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
- CPPFLAGS="$CPPFLAGS -D_REENTRANT"
- ;;
- esac
- # Some systems optimize for single-threaded programs by default, and
- # need special flags to disable these optimizations. For example, the
- # definition of 'errno' in <errno.h>.
- case "$host_os" in
- aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
- solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
- esac
+ if test "$gl_use_threads" = yes \
+ || test "$gl_use_threads" = isoc \
+ || test "$gl_use_threads" = posix \
+ || test "$gl_use_threads" = isoc+posix; then
+ # For using <threads.h> or <pthread.h>:
+ gl_ANYTHREADLIB_EARLY
fi
])
@@ -114,108 +453,31 @@
LTLIBMULTITHREAD=
if test "$gl_use_threads" != no; then
dnl Check whether the compiler and linker support weak declarations.
- AC_CACHE_CHECK([whether imported symbols can be declared weak],
- [gl_cv_have_weak],
- [gl_cv_have_weak=no
- dnl First, test whether the compiler accepts it syntactically.
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[extern void xyzzy ();
-#pragma weak xyzzy]],
- [[xyzzy();]])],
- [gl_cv_have_weak=maybe])
- if test $gl_cv_have_weak = maybe; then
- dnl Second, test whether it actually works. On Cygwin 1.7.2, with
- dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
- AC_RUN_IFELSE(
- [AC_LANG_SOURCE([[
-#include <stdio.h>
-#pragma weak fputs
-int main ()
-{
- return (fputs == NULL);
-}]])],
- [gl_cv_have_weak=yes],
- [gl_cv_have_weak=no],
- [dnl When cross-compiling, assume that only ELF platforms support
- dnl weak symbols.
- AC_EGREP_CPP([Extensible Linking Format],
- [#ifdef __ELF__
- Extensible Linking Format
- #endif
- ],
- [gl_cv_have_weak="guessing yes"],
- [gl_cv_have_weak="guessing no"])
- ])
- fi
- ])
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
- # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
- # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY.
- AC_CHECK_HEADER([pthread.h],
- [gl_have_pthread_h=yes], [gl_have_pthread_h=no])
- if test "$gl_have_pthread_h" = yes; then
- # Other possible tests:
- # -lpthreads (FSU threads, PCthreads)
- # -lgthreads
- gl_have_pthread=
- # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
- # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
- # the second one only in libpthread, and lock.c needs it.
- #
- # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04
- # needs -pthread for some reason. See:
- # http://lists.gnu.org/archive/html/bug-gnulib/2014-09/msg00023.html
- save_LIBS=$LIBS
- for gl_pthread in '' '-pthread'; do
- LIBS="$LIBS $gl_pthread"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <pthread.h>
- pthread_mutex_t m;
- pthread_mutexattr_t ma;
- ]],
- [[pthread_mutex_lock (&m);
- pthread_mutexattr_init (&ma);]])],
- [gl_have_pthread=yes
- LIBTHREAD=$gl_pthread LTLIBTHREAD=$gl_pthread
- LIBMULTITHREAD=$gl_pthread LTLIBMULTITHREAD=$gl_pthread])
- LIBS=$save_LIBS
- test -n "$gl_have_pthread" && break
- done
-
- # Test for libpthread by looking for pthread_kill. (Not pthread_self,
- # since it is defined as a macro on OSF/1.)
- if test -n "$gl_have_pthread" && test -z "$LIBTHREAD"; then
- # The program links fine without libpthread. But it may actually
- # need to link with libpthread in order to create multiple threads.
- AC_CHECK_LIB([pthread], [pthread_kill],
- [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
- # On Solaris and HP-UX, most pthread functions exist also in libc.
- # Therefore pthread_in_use() needs to actually try to create a
- # thread: pthread_create from libc will fail, whereas
- # pthread_create will actually create a thread.
- case "$host_os" in
- solaris* | hpux*)
- AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
- [Define if the pthread_in_use() detection is hard.])
- esac
- ])
- elif test -z "$gl_have_pthread"; then
- # Some library is needed. Try libpthread and libc_r.
- AC_CHECK_LIB([pthread], [pthread_kill],
- [gl_have_pthread=yes
- LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
- LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
- if test -z "$gl_have_pthread"; then
- # For FreeBSD 4.
- AC_CHECK_LIB([c_r], [pthread_kill],
- [gl_have_pthread=yes
- LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
- LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
- fi
- fi
- if test -n "$gl_have_pthread"; then
+ gl_WEAK_SYMBOLS
+ if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+ dnl If we use weak symbols to implement pthread_in_use / pth_in_use /
+ dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create
+ dnl facility is in use.
+ AC_CHECK_HEADERS_ONCE([threads.h])
+ :
+ fi
+ if test "$gl_use_threads" = isoc || test "$gl_use_threads" = isoc+posix; then
+ AC_CHECK_HEADERS_ONCE([threads.h])
+ gl_have_isoc_threads="$ac_cv_header_threads_h"
+ fi
+ if test "$gl_use_threads" = yes \
+ || test "$gl_use_threads" = posix \
+ || test "$gl_use_threads" = isoc+posix; then
+ gl_PTHREADLIB_BODY
+ LIBTHREAD=$LIBPTHREAD LTLIBTHREAD=$LIBPTHREAD
+ LIBMULTITHREAD=$LIBPMULTITHREAD LTLIBMULTITHREAD=$LIBPMULTITHREAD
+ if test $gl_pthread_api = yes; then
+ if test "$gl_use_threads" = isoc+posix && test "$gl_have_isoc_threads" = yes; then
+ gl_threads_api='isoc+posix'
+ AC_DEFINE([USE_ISOC_AND_POSIX_THREADS], [1],
+ [Define if the combination of the ISO C and POSIX multithreading APIs can be used.])
+ LIBTHREAD= LTLIBTHREAD=
+ else
gl_threads_api=posix
AC_DEFINE([USE_POSIX_THREADS], [1],
[Define if the POSIX multithreading library can be used.])
@@ -223,75 +485,34 @@
if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
AC_DEFINE([USE_POSIX_THREADS_WEAK], [1],
[Define if references to the POSIX multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
+ LIBTHREAD= LTLIBTHREAD=
+ else
+ case "$host_os" in
+ freebsd* | dragonfly*)
+ if test "x$LIBTHREAD" != "x$LIBMULTITHREAD"; then
+ dnl If weak symbols can't tell whether pthread_create(), pthread_key_create()
+ dnl etc. will succeed, we need a runtime test.
+ AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],
+ [Define if the pthread_in_use() detection is hard.])
+ fi
+ ;;
+ esac
fi
fi
fi
fi
fi
- if test -z "$gl_have_pthread"; then
- if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
- gl_have_solaristhread=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS -lthread"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[
-#include <thread.h>
-#include <synch.h>
- ]],
- [[thr_self();]])],
- [gl_have_solaristhread=yes])
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_solaristhread"; then
- gl_threads_api=solaris
- LIBTHREAD=-lthread
- LTLIBTHREAD=-lthread
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_SOLARIS_THREADS], [1],
- [Define if the old Solaris multithreading library can be used.])
- if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
- AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1],
- [Define if references to the old Solaris multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
+ if test $gl_threads_api = none; then
+ if test "$gl_use_threads" = isoc && test "$gl_have_isoc_threads" = yes; then
+ gl_STDTHREADLIB_BODY
+ LIBTHREAD=$LIBSTDTHREAD LTLIBTHREAD=$LIBSTDTHREAD
+ LIBMULTITHREAD=$LIBSTDTHREAD LTLIBMULTITHREAD=$LIBSTDTHREAD
+ gl_threads_api=isoc
+ AC_DEFINE([USE_ISOC_THREADS], [1],
+ [Define if the ISO C multithreading library can be used.])
fi
fi
- if test "$gl_use_threads" = pth; then
- gl_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_LINKFLAGS([pth])
- gl_have_pth=
- gl_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBPTH"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([[#include <pth.h>]], [[pth_self();]])],
- [gl_have_pth=yes])
- LIBS="$gl_save_LIBS"
- if test -n "$gl_have_pth"; then
- gl_threads_api=pth
- LIBTHREAD="$LIBPTH"
- LTLIBTHREAD="$LTLIBPTH"
- LIBMULTITHREAD="$LIBTHREAD"
- LTLIBMULTITHREAD="$LTLIBTHREAD"
- AC_DEFINE([USE_PTH_THREADS], [1],
- [Define if the GNU Pth multithreading library can be used.])
- if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
- if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
- AC_DEFINE([USE_PTH_THREADS_WEAK], [1],
- [Define if references to the GNU Pth multithreading library should be made weak.])
- LIBTHREAD=
- LTLIBTHREAD=
- fi
- fi
- else
- CPPFLAGS="$gl_save_CPPFLAGS"
- fi
- fi
- if test -z "$gl_have_pthread"; then
+ if test $gl_threads_api = none; then
case "$gl_use_threads" in
yes | windows | win32) # The 'win32' is for backward compatibility.
if { case "$host_os" in
@@ -333,6 +554,21 @@
])
+dnl gl_AVOID_WINPTHREAD
+dnl -------------------
+dnl Sets the gl_THREADLIB default so that on mingw, a dependency to the
+dnl libwinpthread DLL (mingw-w64 winpthreads library) is avoided.
+dnl The user can still override it at installation time, by using the
+dnl configure option '--enable-threads'.
+
+AC_DEFUN([gl_AVOID_WINPTHREAD], [
+ m4_divert_text([INIT_PREPARE], [gl_use_winpthreads_default=no])
+])
+
+
+dnl ============================================================================
+
+
dnl Survey of platforms:
dnl
dnl Platform Available Compiler Supports test-lock
@@ -362,7 +598,6 @@
dnl Mac OS X 10.[123] posix -lpthread Y OK
dnl
dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK
-dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK
dnl
dnl HP-UX 11 posix -lpthread N (cc) OK
dnl Y (gcc)
@@ -376,8 +611,6 @@
dnl
dnl Cygwin posix -lpthread Y OK
dnl
-dnl Any of the above pth -lpth 0.0
-dnl
dnl Mingw windows N OK
dnl
dnl BeOS 5 --
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/tsearch.m4
^
|
@@ -1,5 +1,5 @@
-# tsearch.m4 serial 6
-dnl Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# tsearch.m4 serial 8
+dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -7,7 +7,7 @@
AC_DEFUN([gl_FUNC_TSEARCH],
[
AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
- AC_CHECK_FUNCS([tsearch])
+ AC_CHECK_FUNCS([tsearch twalk])
if test $ac_cv_func_tsearch = yes; then
dnl On OpenBSD 4.0, the return value of tdelete() is incorrect.
AC_REQUIRE([AC_PROG_CC])
@@ -38,8 +38,10 @@
return result;
}]])], [gl_cv_func_tdelete_works=yes], [gl_cv_func_tdelete_works=no],
[case "$host_os" in
- openbsd*) gl_cv_func_tdelete_works="guessing no";;
- *) gl_cv_func_tdelete_works="guessing yes";;
+ openbsd*) gl_cv_func_tdelete_works="guessing no" ;;
+ # Guess yes on native Windows.
+ mingw*) gl_cv_func_tdelete_works="guessing yes" ;;
+ *) gl_cv_func_tdelete_works="guessing yes" ;;
esac
])
])
@@ -51,6 +53,9 @@
else
HAVE_TSEARCH=0
fi
+ if test $ac_cv_func_twalk != yes; then
+ HAVE_TWALK=0
+ fi
])
# Prerequisites of lib/tsearch.c.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/visibility.m4
^
|
@@ -1,5 +1,5 @@
-# visibility.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2005, 2008, 2010-2016 Free Software Foundation, Inc.
+# visibility.m4 serial 6
+dnl Copyright (C) 2005, 2008, 2010-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -29,42 +29,42 @@
dnl First, check whether -Werror can be added to the command line, or
dnl whether it leads to an error because of some other option that the
dnl user has put into $CC $CFLAGS $CPPFLAGS.
- AC_MSG_CHECKING([whether the -Werror option is usable])
- AC_CACHE_VAL([gl_cv_cc_vis_werror], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -Werror"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[]], [[]])],
- [gl_cv_cc_vis_werror=yes],
- [gl_cv_cc_vis_werror=no])
- CFLAGS="$gl_save_CFLAGS"])
- AC_MSG_RESULT([$gl_cv_cc_vis_werror])
+ AC_CACHE_CHECK([whether the -Werror option is usable],
+ [gl_cv_cc_vis_werror],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_vis_werror=yes],
+ [gl_cv_cc_vis_werror=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
dnl Now check whether visibility declarations are supported.
- AC_MSG_CHECKING([for simple visibility declarations])
- AC_CACHE_VAL([gl_cv_cc_visibility], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -fvisibility=hidden"
- dnl We use the option -Werror and a function dummyfunc, because on some
- dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
- dnl "visibility attribute not supported in this configuration; ignored"
- dnl at the first function definition in every compilation unit, and we
- dnl don't want to use the option in this case.
- if test $gl_cv_cc_vis_werror = yes; then
- CFLAGS="$CFLAGS -Werror"
- fi
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
- extern __attribute__((__visibility__("default"))) int exportedvar;
- extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
- extern __attribute__((__visibility__("default"))) int exportedfunc (void);
- void dummyfunc (void) {}
- ]],
- [[]])],
- [gl_cv_cc_visibility=yes],
- [gl_cv_cc_visibility=no])
- CFLAGS="$gl_save_CFLAGS"])
- AC_MSG_RESULT([$gl_cv_cc_visibility])
+ AC_CACHE_CHECK([for simple visibility declarations],
+ [gl_cv_cc_visibility],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+ dnl We use the option -Werror and a function dummyfunc, because on some
+ dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
+ dnl "visibility attribute not supported in this configuration; ignored"
+ dnl at the first function definition in every compilation unit, and we
+ dnl don't want to use the option in this case.
+ if test $gl_cv_cc_vis_werror = yes; then
+ CFLAGS="$CFLAGS -Werror"
+ fi
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
+ extern __attribute__((__visibility__("default"))) int exportedvar;
+ extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
+ extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+ void dummyfunc (void) {}
+ ]],
+ [[]])],
+ [gl_cv_cc_visibility=yes],
+ [gl_cv_cc_visibility=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
if test $gl_cv_cc_visibility = yes; then
CFLAG_VISIBILITY="-fvisibility=hidden"
HAVE_VISIBILITY=1
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/m4/wint_t.m4
^
|
@@ -1,11 +1,12 @@
-# wint_t.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2003, 2007-2016 Free Software Foundation, Inc.
+# wint_t.m4 serial 10
+dnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
-dnl Test whether <wchar.h> has the 'wint_t' type.
+dnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's
+dnl <wchar.h> or <wctype.h> would, if present, override 'wint_t'.
dnl Prerequisite: AC_PROG_CC
AC_DEFUN([gt_TYPE_WINT_T],
@@ -13,20 +14,44 @@
AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
- [[
-/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
- <wchar.h>.
- BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
- before <wchar.h>. */
-#include <stddef.h>
-#include <stdio.h>
-#include <time.h>
-#include <wchar.h>
+ [[#include <wchar.h>
wint_t foo = (wchar_t)'\0';]],
[[]])],
[gt_cv_c_wint_t=yes],
[gt_cv_c_wint_t=no])])
if test $gt_cv_c_wint_t = yes; then
AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])
+
+ dnl Determine whether gnulib's <wchar.h> or <wctype.h> would, if present,
+ dnl override 'wint_t'.
+ AC_CACHE_CHECK([whether wint_t is large enough],
+ [gl_cv_type_wint_t_large_enough],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <wchar.h>
+ int verify[sizeof (wint_t) < sizeof (int) ? -1 : 1];
+ ]])],
+ [gl_cv_type_wint_t_large_enough=yes],
+ [gl_cv_type_wint_t_large_enough=no])])
+ if test $gl_cv_type_wint_t_large_enough = no; then
+ GNULIB_OVERRIDES_WINT_T=1
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ AC_SUBST([GNULIB_OVERRIDES_WINT_T])
+])
+
+dnl Prerequisites of the 'wint_t' override.
+AC_DEFUN([gl_TYPE_WINT_T_PREREQ],
+[
+ AC_CHECK_HEADERS_ONCE([crtdefs.h])
+ if test $ac_cv_header_crtdefs_h = yes; then
+ HAVE_CRTDEFS_H=1
+ else
+ HAVE_CRTDEFS_H=0
fi
+ AC_SUBST([HAVE_CRTDEFS_H])
])
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/ChangeLog
^
|
@@ -1,5 +1,473 @@
-2016-09-05 gettextize <bug-gnu-gettext@gnu.org>
+2020-07-26 Bruno Haible <bruno@clisp.org>
- * Makefile.in.in: Upgrade to gettext-0.19.8.1.
- * Rules-quot: Upgrade to gettext-0.19.8.1.
+ Update translations (from the TP).
+ * gettext-runtime/po/*.po: Update.
+ * gettext-tools/po/*.po: Update.
+ * gettext-tools/examples/po/*.po: Update.
+ * gettext-tools/examples/po/LINGUAS: Add 'nn'.
+ * gettext-tools/examples/hello-*/po/LINGUAS: Likewise.
+ * gettext-tools/examples/Makefile.am (EXAMPLESPOFILES): Add nn.po.
+ Prepare for 0.21 release.
+ * gettext-runtime/doc/matrix.texi: Update from TP.
+ * gettext-runtime/doc/nls.texi (STATUS): Update.
+ * gettext-runtime/intl/libgnuintl.in.h (LIBINTL_VERSION): Bump.
+ * gettext-tools/libgettextpo/gettext-po.in.h (LIBGETTEXTPO_VERSION): Bump.
+ * libtextstyle/version.sh: Update VERSION_NUMBER, RELEASE_DATE.
+ * gettext-runtime/po/Makefile.in.in: Bump Origin version.
+ * NEWS, libtextstyle/NEWS, gettext-runtime/NEWS: Update.
+ * libtextstyle/lib/Makefile.am (LTV_*): Bump to 1:1:1.
+ * gettext-runtime/intl/Makefile.am (LTV_*): Bump to 10:0:2.
+ * gettext-tools/libgettextpo/Makefile.am (LTV_*): Bump to 5:7:5.
+ * gettext-tools/configure.ac (ARCHIVE_VERSION): Bump to 0.21.
+ * gettext-tools/misc/autopoint.in: Allow version 0.21.
+
+2020-04-14 Bruno Haible <bruno@clisp.org>
+
+ Merge from 0.20.x branch: Update translations (from the TP).
+ * gettext-runtime/po/*.po: Update.
+ * gettext-tools/po/*.po: Update.
+ * gettext-tools/examples/po/*.po: Update.
+ * gettext-tools/examples/po/LINGUAS: Add 'sq'.
+ * gettext-tools/examples/hello-*/po/LINGUAS: Likewise.
+ * gettext-tools/examples/Makefile.am (EXAMPLESPOFILES): Add sq.po.
+
+2020-04-11 Bruno Haible <bruno@clisp.org>
+
+ po: Emit a warning when creating a tarball without POT file.
+ * gettext-runtime/po/Makefile.in.in (dist2): Emit a warning when the POT file
+ does not exist.
+ * gettext-tools/examples/hello-*/po/Makefile.am (distdir1): Likewise.
+
+2020-04-05 Bruno Haible <bruno@clisp.org>
+
+ po, examples: In the .po -> .gmo rules, really consider the newest changes to the POT file.
+ Reported by Petr Ovtchenkov <ptr@void-ptr.info> in
+ <https://lists.gnu.org/archive/html/bug-gnulib/2020-04/msg00000.html>.
+ Helped by Paul Smith.
+
+ * gettext-runtime/po/Makefile.in.in (.po.gmo): Write dependency on the POT file
+ as a target rule, since inference rules don't support prerequisites.
+ * gettext-tools/examples/hello-*/po/Makefile.am: Likewise, also for the .po.qm
+ rule.
+ * NEWS: Mention the fix.
+
+2019-05-12 Bruno Haible <bruno@clisp.org>
+
+ Update translations (from the TP).
+
+ Update bug reporting instructions.
+ * README: Tell users to report bugs in the bug tracker or by email. Use the
+ mailing list address, not the alias.
+ * gettext-runtime/libasprintf/README: Likewise.
+ * gettext-tools/doc/gettext.texi (Introduction): Likewise.
+ (Plural forms): Use the mailing list address, not the alias.
+ * configure.ac (AC_INIT): Use the mailing list address, not the alias.
+ * gettext-runtime/configure.ac (AC_INIT): Likewise.
+ * gettext-tools/configure.ac (AC_INIT): Likewise.
+ * gettext-tools/examples/configure.ac (AC_INIT): Likewise.
+ * gettext-runtime/po/Makevars (MSGID_BUGS_ADDRESS): Use the mailing list
+ address, not the alias.
+ * gettext-tools/po/Makevars (MSGID_BUGS_ADDRESS): Likewise.
+ * gettext-tools/examples/po/Makefile.am (MSGID_BUGS_ADDRESS): Likewise.
+ * gettext-tools/examples/hello-*/po/Makevars (MSGID_BUGS_ADDRESS): Likewise.
+ * gettext-tools/examples/hello-*/po/Makefile.am (MSGID_BUGS_ADDRESS): Likewise.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile (MSGID_BUGS_ADDRESS):
+ Likewise.
+ * gettext-tools/examples/hello-c++-kde/hello.cc (main): Likewise.
+ * gettext-runtime/src/envsubst.c (main): Move URL out of translatable string.
+ (usage): Tell users to report bugs in the bug tracker or by email. Use the
+ mailing list address, not the alias.
+ * gettext-runtime/src/gettext.c: Likewise.
+ * gettext-runtime/src/ngettext.c: Likewise.
+ * gettext-tools/src/cldr-plurals.c: Likewise.
+ * gettext-tools/src/hostname.c: Likewise.
+ * gettext-tools/src/msgattrib.c: Likewise.
+ * gettext-tools/src/msgcat.c: Likewise.
+ * gettext-tools/src/msgcmp.c: Likewise.
+ * gettext-tools/src/msgcomm.c: Likewise.
+ * gettext-tools/src/msgconv.c: Likewise.
+ * gettext-tools/src/msgen.c: Likewise.
+ * gettext-tools/src/msgexec.c: Likewise.
+ * gettext-tools/src/msgfilter.c: Likewise.
+ * gettext-tools/src/msgfmt.c: Likewise.
+ * gettext-tools/src/msggrep.c: Likewise.
+ * gettext-tools/src/msginit.c: Likewise.
+ * gettext-tools/src/msgmerge.c: Likewise.
+ * gettext-tools/src/msgunfmt.c: Likewise.
+ * gettext-tools/src/msguniq.c: Likewise.
+ * gettext-tools/src/recode-sr-latin.c: Likewise.
+ * gettext-tools/src/urlget.c: Likewise.
+ * gettext-tools/src/xgettext.c: Likewise.
+ * gettext-tools/tests/tstgettext.c: Likewise.
+ * gettext-tools/tests/tstngettext.c: Likewise.
+ * gettext-tools/misc/autopoint.in (func_usage): Tell users to report bugs in the
+ bug tracker or by email. Use the mailing list address, not the alias.
+ * gettext-tools/misc/convert-archive.in (func_usage): Likewise.
+ * gettext-tools/misc/gettextize.in (func_usage): Likewise.
+
+2019-05-08 Bruno Haible <bruno@clisp.org>
+
+ Update translations (from the TP).
+
+2019-04-28 Bruno Haible <bruno@clisp.org>
+
+ In the POT files, talk about the "GNU gettext package".
+ Reported by Benno Schulenberg <coordinator@translationproject.org>.
+
+ * gettext-runtime/po/Makevars (XGETTEXT_OPTIONS): Add --package-name option.
+ * gettext-tools/po/Makevars (XGETTEXT_OPTIONS): Likewise.
+ * gettext-tools/examples/po/Makefile.am (XGETTEXT_OPTIONS): New variable.
+
+2019-04-28 Bruno Haible <bruno@clisp.org>
+
+ po: Make it possible to override xgettext options from Makefile.in.in.
+ * gettext-runtime/po/Makefile.in.in ($(DOMAIN).pot-update): List the
+ XGETTEXT_OPTIONS and the XGETTEXT_EXTRA_OPTIONS after all other options.
+ * gettext-tools/examples/po/Makefile.am ($(DOMAIN).pot-update): Likewise.
+ * gettext-tools/examples/hello-*/po/Makefile.am ($(DOMAIN).pot-update):
+ Likewise.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile
+ ($(DOMAIN).pot-update): Likewise.
+ * NEWS: Mention the change.
+ * gettext-tools/doc/gettext.texi (po/Makevars): Fix typo.
+
+2019-04-14 Bruno Haible <bruno@clisp.org>
+
+ Update translations (from the TP).
+ * gettext-runtime/po/*.po: Update.
+ * gettext-runtime/po/LINGUAS: Add 'ast'.
+ * gettext-tools/po/*.po: Update.
+ * gettext-tools/examples/po/*.po: Update.
+ * gettext-tools/examples/po/LINGUAS: Add 'ta'.
+ * gettext-tools/examples/hello-*/po/LINGUAS: Likewise.
+ * gettext-tools/examples/Makefile.am (EXAMPLESPOFILES): Add ta.po.
+
+ Prepare for 0.20 release.
+ * gettext-runtime/intl/libgnuintl.in.h (LIBINTL_VERSION): Update.
+ * gettext-tools/libgettextpo/gettext-po.in.h (LIBGETTEXTPO_VERSION): Update.
+ * gettext-runtime/m4/gettext.m4: Bump version number in comment.
+ * gettext-runtime/m4/intl.m4: Likewise.
+ * gettext-runtime/m4/intlmacosx.m4: Likewise.
+ * gettext-runtime/m4/po.m4: Likewise.
+ (GETTEXT_MACRO_VERSION): Bump to 0.20.
+ * gettext-runtime/po/Makefile.in.in (GETTEXT_MACRO_VERSION): Likewise.
+ * gettext-runtime/intl/Makefile.am (LTV_*): Bump to 9:6:2.
+ * gettext-tools/libgettextpo/Makefile.am (LTV_*): Bump to 5:5:5.
+ * gettext-tools/configure.ac (ARCHIVE_VERSION): Set to 0.20.
+ * gettext-tools/misc/autopoint.in: Accept version 0.20.
+ * gettext-runtime/doc/matrix.texi: Update from TP.
+ * gettext-runtime/doc/nls.texi (STATUS): Update.
+ * gettext-runtime/src/envsubst.c (main): Update copyright year in --version
+ output.
+ * gettext-runtime/src/gettext.c (main): Likewise.
+ * gettext-runtime/src/ngettext.c (main): Likewise.
+ * gettext-tools/src/cldr-plurals.c (main): Likewise.
+ * gettext-tools/src/hostname.c (main): Likewise.
+ * gettext-tools/src/msgattrib.c (main): Likewise.
+ * gettext-tools/src/msgcat.c (main): Likewise.
+ * gettext-tools/src/msgcmp.c (main): Likewise.
+ * gettext-tools/src/msgcomm.c (main): Likewise.
+ * gettext-tools/src/msgconv.c (main): Likewise.
+ * gettext-tools/src/msgen.c (main): Likewise.
+ * gettext-tools/src/msgexec.c (main): Likewise.
+ * gettext-tools/src/msgfilter.c (main): Likewise.
+ * gettext-tools/src/msgfmt.c (main): Likewise.
+ * gettext-tools/src/msggrep.c (main): Likewise.
+ * gettext-tools/src/msginit.c (main): Likewise.
+ * gettext-tools/src/msgmerge.c (main): Likewise.
+ * gettext-tools/src/msgunfmt.c (main): Likewise.
+ * gettext-tools/src/msguniq.c (main): Likewise.
+ * gettext-tools/src/recode-sr-latin.c (main): Likewise.
+ * gettext-tools/src/urlget.c (main): Likewise.
+ * gettext-tools/src/xgettext.c (main): Likewise.
+ * gettext-runtime/src/gettext.sh.in (func_version): Update copyright year.
+ * gettext-tools/misc/convert-archive.in (func_version): Likewise.
+ * gettext-tools/misc/gettextize.in (func_version): Likewise.
+ * libtextstyle/version.sh: Use version number 0.20 here as well.
+ * gettext-runtime/NEWS: Mention changes (from main NEWS).
+ * libtextstyle/NEWS: Mention changes.
+
+2019-04-04 Bruno Haible <bruno@clisp.org>
+
+ Add copyright notices in several files.
+ Reported by <ineiev@gnu.org> in <https://savannah.gnu.org/bugs/?54809>.
+
+ * gettext-runtime/m4/Makefile.am: Add GPL copyright notice.
+ * gettext-tools/m4/Makefile.am: Likewise.
+ * gettext-tools/doc/iso-639.sed: Likewise.
+ * gettext-tools/doc/iso-639-2.sed: Likewise.
+ * gettext-tools/doc/iso-3166.sed: Likewise.
+ * gettext-tools/its/glade1.its: Likewise.
+ * gettext-tools/its/glade2.its: Likewise.
+ * gettext-tools/its/gsettings.its: Likewise.
+ * gettext-tools/its/gtkbuilder.its: Likewise.
+ * gettext-tools/misc/cvsuser.c: Likewise.
+ * gettext-tools/projects/team-address: Likewise.
+ * gettext-tools/projects/GNOME/team-address: Likewise.
+ * gettext-tools/projects/GNOME/trigger: Likewise.
+ * gettext-tools/projects/KDE/team-address: Likewise.
+ * gettext-tools/projects/KDE/trigger: Likewise.
+ * gettext-tools/projects/TP/team-address: Likewise.
+ * windows/windres-options: Likewise.
+ * gettext-runtime/po/insert-header.sin: Add copyright notice, based on the one
+ in Rules-quot.
+ * gettext-tools/doc/FAQ.html: Add copyright notice, suitable for documentation.
+
+2018-11-25 Bruno Haible <bruno@clisp.org>
+
+ build: Remove generated files from version control.
+ This creates a bootstrapping issue, but it can be mitigated:
+ If a user wants to build GNU gettext on a platform which does not have the
+ GNU gettext programs installed, they first need to build and install a tarball
+ of GNU gettext; then only they can build GNU gettext from the git repository.
+
+ * gettext-runtime/po/gettext-runtime.pot: Remove file.
+ * gettext-tools/po/gettext-tools.pot: Remove file.
+ * gettext-tools/examples/po/gettext-examples.pot: Remove file.
+
+2018-10-25 Bruno Haible <bruno@clisp.org>
+
+ po, examples: Change .po -> .gmo rules to consider the newest changes to the POT file.
+ Reported by Claude Paroz <claude@2xlibre.net>
+ in <https://savannah.gnu.org/bugs/?50910>.
+
+ * gettext-runtime/m4/po.m4 (AM_PO_SUBDIRS): Set MSGMERGE_FOR_MSGFMT_OPTION.
+ * gettext-runtime/po/Makefile.in.in (MSGMERGE): Use GNU msgmerge, even if not
+ first in $PATH.
+ (MSGMERGE_FOR_MSGFMT_OPTION): New variable.
+ (.po.gmo): Depend on the POT file. Use msgmerge on the fly, to take into
+ account the most recent POT file changes.
+ * gettext-tools/examples/hello-*/po/Makefile.am: Likewise, also for the .po.qm,
+ update-properties, update-classes targets.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile
+ (MSGMERGE_FOR_MSGFMT_OPTION): New variable.
+ ($(STRINGSFILES)): Depend on the POT file. Use msgmerge on the fly, to take
+ into account the most recent POT file changes.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po, examples: Put stamp-po in the source directory.
+ Rationale: <https://www.gnu.org/prep/standards/html_node/Makefile-Basics.html>.
+
+ * gettext-runtime/po/Makefile.in.in: Use $(srcdir)/stamp-po instead of stamp-po.
+ Talk about "version control system", not CVS.
+ * gettext-tools/examples/hello-*/po/Makefile.am: Likewise.
+ * gettext-tools/examples/po/Makefile.am: Likewise.
+ * gettext-tools/examples/check-examples (func_check_dist_vpath): Verify the
+ stamp-po file does not exist in the build dir, except when using the older
+ Makefile.in.in infrastructure.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po: Make "make maintainer-clean" erase the .pot file.
+ Rationale:
+ <https://www.gnu.org/prep/standards/html_node/Standard-Targets.html>
+ <https://www.gnu.org/software/automake/manual/html_node/Clean.html>
+
+ * NEWS: Mention the change.
+ * gettext-runtime/po/Makefile.in.in (maintainer-clean): Remove the .pot file.
+ * gettext-tools/examples/hello-*/po/Makefile.am (MAINTAINERCLEANFILES): Add
+ the .pot file.
+ * gettext-tools/examples/po/Makefile.am (MAINTAINERCLEANFILES): Likewise.
+ * gettext-tools/examples/check-examples (func_check_maintainerclean,
+ func_check_maintainerclean_vpath): Verify the .pot file is removed after
+ 'make maintainer-clean', except when using the older Makefile.in.in
+ infrastructure.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po, examples: Use case-insensitive search for "GNU <PACKAGE_NAME>".
+ Reported by Akim Demaille <akim@lrde.epita.fr> in
+ <https://lists.gnu.org/archive/html/bug-gettext/2018-10/msg00020.html>.
+
+ * gettext-runtime/po/Makefile.in.in ($(DOMAIN).pot-update): Use a
+ case-insensitive search for "GNU <PACKAGE_NAME>".
+ * gettext-tools/examples/hello-*/po/Makefile.am ($(DOMAIN).pot-update):
+ Likewise.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile
+ ($(DOMAIN).pot-update): Likewise.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po: Remove obsolete Makefile rules for .mo files.
+ * gettext-runtime/po/Makefile.in.in (MSGFMT*): Remove variables.
+ (.SUFFIXES): Remove .mo.
+ (.po.mo): Remove rule.
+ (distclean): Don't remove *.mo files.
+ * gettext-tools/examples/hello-*/po/Makefile.am (.SUFFIXES): Remove .mo.
+ (.po.mo): Remove rule.
+ (DISTCLEANFILES): Remove *.mo.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile (.SUFFIXES):
+ Remove .mo.
+ * gettext-runtime/m4/po.m4 (AM_PO_SUBDIRS): Don't set MSGFMT_015.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ examples: Add an option to claim the package as GNU/non-GNU.
+ This mirrors the Makefile.in.in and Makevars change from 2014-05-01.
+
+ Reported by David Shea at <https://savannah.gnu.org/bugs/?40520>.
+
+ * gettext-runtime/po/Makefile.in.in ($(DOMAIN).pot-update): Tweak whitespace.
+ * gettext-tools/examples/hello-*/po/Makefile.am (PACKAGE_GNU): New variable.
+ ($(DOMAIN).pot-update): Don't search for "GNU packagename" if $(PACKAGE_GNU) is
+ set.
+ * gettext-tools/examples/hello-objc-gnustep/po/GNUmakefile: Likewise.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po: Make the insertion of the .pot-header file more robust.
+ This improves on the 2015-09-01 patch.
+
+ * gettext-runtime/po/Makefile.in.in ($(DOMAIN).pot-update): Fail if the 'cat'
+ command fails.
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po: When doing msgmerge --version, use the correct msgmerge program.
+ This reverts the patch from
+ <https://lists.gnu.org/archive/html/bug-gettext/2015-06/msg00000.html>.
+ Rationale:
+ <https://lists.gnu.org/archive/html/bug-gettext/2018-10/msg00000.html>.
+
+ * gettext-runtime/po/Makefile.in.in ($(POFILES)): Use $(MSGMERGE_UPDATE),
+ not $(MSGMERGE).
+
+2018-10-24 Bruno Haible <bruno@clisp.org>
+
+ po: Make $(POFILES) target more robust.
+ It was introduced on 2014-05-01.
+
+ * gettext-runtime/po/Makefile.in.in ($(POFILES)): Create POT file also when the
+ PO file does not yet exist. Fail if creation of the POT file fails.
+
+2018-05-05 Bruno Haible <bruno@clisp.org>
+
+ all: Replace more http and ftp URLs by https URLs.
+ * autogen.sh: Use https: URLs.
+ * gettext-runtime/doc/nls.texi (Translating Teams, Available Packages): Likewise.
+ * gettext-tools/doc/gettext.texi: Likewise.
+ * gettext-tools/doc/FAQ.html: Likewise.
+ * gettext-tools/doc/tutorial.html: Likewise.
+ * gettext-tools/misc/gettextize.in: Likewise.
+ * gettext-tools/projects/GNOME/team-address: Likewise.
+ * gettext-tools/projects/GNOME/teams.url: Likewise.
+ * gettext-tools/projects/KDE/team-address: Likewise.
+ * gettext-tools/projects/KDE/teams.url: Likewise.
+ * gettext-tools/projects/TP/teams.url: Likewise.
+ * gettext-tools/src/x-python.c: Likewise.
+ * gettext-tools/tests/xgettext-its-1: Likewise.
+
+2017-10-15 Bruno Haible <bruno@clisp.org>
+
+ Clarify copyright and license of some files.
+ Reported by Joël Krähemann at <https://savannah.gnu.org/bugs/?52227>.
+
+ * gettext-runtime/po/Makefile.in.in: Correct copyright holder.
+ * gettext-runtime/po/remove-potcdate.sin: Use the same licensing terms as Makefile.in.in.
+ * gettext-runtime/po/Rules-quot: Use an all-permissive license.
+ * gettext-tools/po/Makevars.template: Likewise.
+ * gettext-runtime/po/Makevars: Likewise.
+ * gettext-tools/po/Makevars: Likewise.
+ * gettext-runtime/po/POTFILES.in: Use GPLv3+.
+ * gettext-tools/po/POTFILES.in: Likewise.
+
+2017-02-16 Bruno Haible <bruno@clisp.org>
+
+ Support for Automake targets install-{dvi,ps,pdf,html}.
+ Reported by Eric Blake at https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25690
+ via Assaf Gordon.
+
+ * gettext-runtime/po/Makefile.in.in (install-dvi, install-ps, install-pdf,
+ install-html): New empty targets.
+
+2016-12-11 Bruno Haible <bruno@clisp.org>
+
+ Merge all .gitignore files into a single .gitignore file.
+
+ Update and organize the .gitignore files.
+
+2016-07-09 Stanislav Brabec <sbrabec@suse.com>
+
+ Add support for msgmerge --previous
+ msgmerge --previous is a very useful feature that makes adjusting of
+ translation much easier when small changes in the source code are done.
+ msgmerge supports it for 10 years, but it is not used by most projects,
+ as Makefile.in.in never added support for it.
+
+ Use msgmerge --previous as default on all systems with gettext >= 0.16.
+
+2016-06-09 Daiki Ueno <ueno@gnu.org>
+
+ Update translations
+ * gettext-runtime/po/eo.po: Update from Felipe Castro <fefcas@gmail.com>
+ * gettext-runtime/po/hr.po: Update from Božidar Putanec <bozidarp@yahoo.com>
+ * gettext-runtime/po/sv.po: Update from Göran Uddeborg <goeran@uddeborg.se>
+ * gettext-tools/examples/po/eo.po: Update from Felipe Castro <fefcas@gmail.com>
+ * gettext-tools/examples/po/hr.po: Update from Božidar Putanec <bozidarp@yahoo.com>
+ * gettext-tools/examples/po/sv.po: Update from Göran Uddeborg <goeran@uddeborg.se>
+ * gettext-tools/po/bg.po: Update from Roumen Petrov <transl@roumenpetrov.info>
+ * gettext-tools/po/es.po: Update from Antonio Ceballos <aceballos@gmail.com>
+ * gettext-tools/po/fr.po: Update from Stéphane Aulery <lkppo@free.fr>
+ * gettext-tools/po/ja.po: Update from Masahito Yamaga <ma@yama-ga.com>
+ * gettext-tools/po/ko.po: Update from Changwoo Ryu <cwryu@debian.org>
+ * gettext-tools/po/nl.po: Update from Benno Schulenberg <benno@vertaalt.nl>
+ * gettext-tools/po/pl.po: Update from Rafał Maszkowski <rzm@icm.edu.pl>
+ * gettext-tools/po/sk.po: Update from Marcel Telka <marcel@telka.sk>
+ * gettext-tools/po/sr.po: Update from Мирослав Николић <miroslavnikolic@rocketmail.com>
+ * gettext-tools/po/sv.po: Update from Göran Uddeborg <goeran@uddeborg.se>
+ * gettext-tools/po/tr.po: Update from Nilgün Belma Bugüner <nilgun@buguner.name.tr>
+ * gettext-tools/po/uk.po: Update from Yuri Chornoivan <yurchor@ukr.net>
+ * gettext-tools/po/vi.po: Update from Trần Ngọc Quân <vnwildman@gmail.com>
+
+ Prepare for 0.19.8
+
+2016-01-02 Daiki Ueno <ueno@gnu.org>
+
+ maint: Update copyright year
+
+2015-12-27 Daiki Ueno <ueno@gnu.org>
+
+ Update translations
+ * gettext-runtime/po/fr.po: Update from Stéphane Aulery <lkppo@free.fr>.
+ * gettext-runtime/po/nb.po: Update from Johnny A. Solbu <johnny@solbu.net>.
+ * gettext-runtime/po/pt_BR.po: Update from Rafael Ferreira <rffontenelle@gmail.com>.
+ * gettext-runtime/po/sr.po: Update from Мирослав Николић <miroslavnikolic@rocketmail.com>.
+ * gettext-runtime/po/zh_TW.po: Update from Wei-Lun Chao <bluebat@member.fsf.org>.
+ * gettext-tools/examples/po/fr.po: Update from Stéphane Aulery <lkppo@free.fr>.
+ * gettext-tools/examples/po/nb.po: Update from Johnny A. Solbu <johnny@solbu.net>.
+ * gettext-tools/examples/po/pt_BR.po: Update from Rafael Ferreira <rffontenelle@gmail.com>.
+ * gettext-tools/examples/po/sr.po: Update from Мирослав Николић <miroslavnikolic@rocketmail.com>.
+ * gettext-tools/examples/po/zh_TW.po: Update from Wei-Lun Chao <bluebat@member.fsf.org>.
+ * gettext-tools/po/bg.po: Update from Roumen Petrov <transl@roumenpetrov.info>.
+ * gettext-tools/po/es.po: Update from Antonio Ceballos <aceballos@gmail.com>.
+ * gettext-tools/po/fr.po: Update from Stéphane Aulery <lkppo@free.fr>.
+ * gettext-tools/po/ja.po: Update from Masahito Yamaga <ma@yama-ga.com>.
+ * gettext-tools/po/nl.po: Update from Benno Schulenberg <benno@vertaalt.nl>.
+ * gettext-tools/po/pt_BR.po: Update from Rafael Fontenelle <rffontenelle@gmail.com>.
+ * gettext-tools/po/sk.po: Update from Marcel Telka <marcel@telka.sk>.
+ * gettext-tools/po/sl.po: Update from Primoz PETERLIN <primozz.peterlin@gmail.com>.
+ * gettext-tools/po/sr.po: Update from Мирослав Николић <miroslavnikolic@rocketmail.com>.
+ * gettext-tools/po/uk.po: Update from Yuri Chornoivan <yurchor@ukr.net>.
+ * gettext-tools/po/vi.po: Update from Trần Ngọc Quân <vnwildman@gmail.com>.
+
+ Prepare for 0.19.7
+
+2015-12-17 Daiki Ueno <ueno@gnu.org>
+
+ po: Prefer to use host tools when cross compiling
+ * gettext-runtime/po/Makefile.in.in (CROSS_COMPILING): New substitute
+ variable.
+ (.nop.po-update): Don't prepend ../src to $PATH when cross compiling.
+ * gettext-runtime/po/Rules-quot (.insert-header.po-update-en): Likewise.
+
+2015-10-15 Daiki Ueno <ueno@gnu.org>
+
+ build: Generate ChangeLogs for intl and po
+ * autogen.sh: Create empty ChangeLog files under intl and po.
+ * Makefile.am (gen-ChangeLogs): Rename from gen-ChangeLog. Generate
+ ChangeLog files for */intl and */po as well as top-level.
+ * gettext-runtime/intl/ChangeLog.0: Rename from ChangeLog.
+ * gettext-runtime/po/ChangeLog.0: Rename from ChangeLog.
+ * gettext-tools/po/ChangeLog.1: Rename from ChangeLog.
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/Makefile.in.in
^
|
@@ -1,13 +1,14 @@
# Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+# Copyright (C) 1995-2000 Ulrich Drepper <drepper@gnu.ai.mit.edu>
+# Copyright (C) 2000-2020 Free Software Foundation, Inc.
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
#
-# Origin: gettext-0.19.8
-GETTEXT_MACRO_VERSION = 0.19
+# Origin: gettext-0.21
+GETTEXT_MACRO_VERSION = 0.20
PACKAGE = @PACKAGE@
VERSION = @VERSION@
@@ -18,12 +19,8 @@
@SET_MAKE@
srcdir = @srcdir@
-# Modified to fit MHD needs
-top_po_srcdir = @top_srcdir@
-top_srcdir = @top_srcdir@/..
-top_po_builddir = $(top_builddir)/po
-# See '$(POTFILES):' rule
-VPATH = @srcdir@:@srcdir@/po
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -56,16 +53,13 @@
GMSGFMT_no = @GMSGFMT@
GMSGFMT_yes = @GMSGFMT_015@
GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-MSGFMT_ = @MSGFMT@
-MSGFMT_no = @MSGFMT@
-MSGFMT_yes = @MSGFMT_015@
-MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
XGETTEXT_ = @XGETTEXT@
XGETTEXT_no = @XGETTEXT@
XGETTEXT_yes = @XGETTEXT_015@
XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
+MSGMERGE = @MSGMERGE@
MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
MSGINIT = msginit
MSGCONV = msgconv
MSGFILTER = msgfilter
@@ -96,27 +90,44 @@
# Makevars gets inserted here. (Don't remove this line!)
-.SUFFIXES:
-.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+all: all-@USE_NLS@
-.po.mo:
- @echo "$(MSGFMT) -c -o $@ $<"; \
- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+.SUFFIXES:
+.SUFFIXES: .po .gmo .sed .sin .nop .po-create .po-update
+
+# The .pot file, stamp-po, .po files, and .gmo files appear in release tarballs.
+# The GNU Coding Standards say in
+# <https://www.gnu.org/prep/standards/html_node/Makefile-Basics.html>:
+# "GNU distributions usually contain some files which are not source files
+# ... . Since these files normally appear in the source directory, they
+# should always appear in the source directory, not in the build directory.
+# So Makefile rules to update them should put the updated files in the
+# source directory."
+# Therefore we put these files in the source directory, not the build directory.
+
+# During .po -> .gmo conversion, take into account the most recent changes to
+# the .pot file. This eliminates the need to update the .po files when the
+# .pot file has changed, which would be troublesome if the .po files are put
+# under version control.
+$(GMOFILES): $(srcdir)/$(DOMAIN).pot
.po.gmo:
@lang=`echo $* | sed -e 's,.*/,,'`; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.1po && rm -f $${lang}.1po"; \
+ cd $(srcdir) && \
+ rm -f $${lang}.gmo && \
+ $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && \
+ $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.1po && \
+ mv t-$${lang}.gmo $${lang}.gmo && \
+ rm -f $${lang}.1po
.sin.sed:
sed -e '/^#/d' $< > t-$@
mv t-$@ $@
-all: all-@USE_NLS@
-
-all-yes: stamp-po
+all-yes: $(srcdir)/stamp-po
all-no:
# Ensure that the gettext macros and this Makefile.in.in are in sync.
@@ -130,24 +141,24 @@
# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
# we don't want to bother translators with empty POT files). We assume that
# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
-# In this case, stamp-po is a nop (i.e. a phony target).
+# In this case, $(srcdir)/stamp-po is a nop (i.e. a phony target).
-# stamp-po is a timestamp denoting the last time at which the CATALOGS have
-# been loosely updated. Its purpose is that when a developer or translator
-# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
-# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
-# invocations of "make" will do nothing. This timestamp would not be necessary
-# if updating the $(CATALOGS) would always touch them; however, the rule for
-# $(POFILES) has been designed to not touch files that don't need to be
-# changed.
-stamp-po: $(srcdir)/$(DOMAIN).pot
+# $(srcdir)/stamp-po is a timestamp denoting the last time at which the CATALOGS
+# have been loosely updated. Its purpose is that when a developer or translator
+# checks out the package from a version control system, and the $(DOMAIN).pot
+# file is not under version control, "make" will update the $(DOMAIN).pot and
+# the $(CATALOGS), but subsequent invocations of "make" will do nothing. This
+# timestamp would not be necessary if updating the $(CATALOGS) would always
+# touch them; however, the rule for $(POFILES) has been designed to not touch
+# files that don't need to be changed.
+$(srcdir)/stamp-po: $(srcdir)/$(DOMAIN).pot
@$(CHECK_MACRO_VERSION)
test ! -f $(srcdir)/$(DOMAIN).pot || \
test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
@test ! -f $(srcdir)/$(DOMAIN).pot || { \
- echo "touch stamp-po" && \
- echo timestamp > stamp-poT && \
- mv stamp-poT stamp-po; \
+ echo "touch $(srcdir)/stamp-po" && \
+ echo timestamp > $(srcdir)/stamp-poT && \
+ mv $(srcdir)/stamp-poT $(srcdir)/stamp-po; \
}
# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
@@ -159,16 +170,13 @@
# The determination of whether the package xyz is a GNU one is based on the
# heuristic whether some file in the top level directory mentions "GNU xyz".
# If GNU 'find' is available, we avoid grepping through monster files.
-# Modified to fit MHD needs
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
package_gnu="$(PACKAGE_GNU)"; \
test -n "$$package_gnu" || { \
if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \
- LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f \
- -size -10000000c -exec grep 'GNU @PACKAGE@' \
- /dev/null '{}' ';' 2>/dev/null; \
+ LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep -i 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \
else \
- LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
+ LC_ALL=C grep -i 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
fi; \
} | grep -v 'libtool:' >/dev/null; then \
package_gnu=yes; \
@@ -188,27 +196,30 @@
fi; \
case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
'' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
- $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_po_srcdir) \
- --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
+ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
+ --add-comments=TRANSLATORS: \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--msgid-bugs-address="$$msgid_bugs_address" \
+ $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
;; \
*) \
- $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_po_srcdir) \
- --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
+ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
+ --add-comments=TRANSLATORS: \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--package-name="$${package_prefix}@PACKAGE@" \
- --package-version='$(VERSION)' \
+ --package-version='@VERSION@' \
--msgid-bugs-address="$$msgid_bugs_address" \
+ $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
;; \
esac
test ! -f $(DOMAIN).po || { \
if test -f $(srcdir)/$(DOMAIN).pot-header; then \
sed -e '1,/^#$$/d' < $(DOMAIN).po > $(DOMAIN).1po && \
- cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po; \
- rm -f $(DOMAIN).1po; \
+ cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po && \
+ rm -f $(DOMAIN).1po \
+ || exit 1; \
fi; \
if test -f $(srcdir)/$(DOMAIN).pot; then \
sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
@@ -233,17 +244,19 @@
# This target rebuilds a PO file if $(DOMAIN).pot has changed.
# Note that a PO file is not touched if it doesn't need to be changed.
$(POFILES): $(POFILESDEPS)
+ @test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot
@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
if test -f "$(srcdir)/$${lang}.po"; then \
- test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot"; \
cd $(srcdir) \
- && { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].*) \
$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+ 0.1[6-7] | 0.1[6-7].*) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --previous $${lang}.po $(DOMAIN).pot;; \
*) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot;; \
esac; \
}; \
else \
@@ -378,61 +391,41 @@
info dvi ps pdf html tags TAGS ctags CTAGS ID:
-# Modified for MHD
+install-dvi install-ps install-pdf install-html:
+
mostlyclean:
rm -f remove-potcdate.sed
- rm -f stamp-poT
+ rm -f $(srcdir)/stamp-poT
rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
rm -fr *.o
- rm -fr po
clean: mostlyclean
-# Modified to fit MHD needs
distclean: clean
- rm -f Makefile Makefile.in POTFILES *.mo
- rm -f config.status config.cache config.log configure.lineno config.status.lineno stamp-po
+ rm -f Makefile Makefile.in POTFILES
-# Modified to fit MHD needs
maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
- rm -f $(GMOFILES)
+ rm -f $(srcdir)/$(DOMAIN).pot $(srcdir)/stamp-po $(GMOFILES)
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-
-# Added for MHD
-# If source path is in absolute form, POTFILES generated with correct path,
-# but if source path in relative form (forced by 'configure' for inplace builds)
-# then POTFILES is generated with extra '..' ('po-directories' in config.status
-# think that '.' is subdirectory and add additional '..' to path to source files)
-# This rule create additional 'po' subdirectory which is included in VPATH.
-$(POTFILES):
- @ case "$(srcdir)" in \
- /* ) : ;; \
- * ) @mkdir_p@ po ;; \
- esac
-
-# Modified to fit MHD needs
-mkdistdir:
- @ $(mkdir_p) $(distdir)
- @ case "$(srcdir)" in \
- /* ) : ;; \
- * ) @mkdir_p@ po ;; \
- esac
-
-# Modified to fit MHD needs
-dist distdir: mkdistdir
+dist distdir:
test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS)
@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
-dist2: stamp-po $(DISTFILES)
- dists="$(DISTFILES)"; \
+dist2: $(srcdir)/stamp-po $(DISTFILES)
+ @dists="$(DISTFILES)"; \
if test "$(PACKAGE)" = "gettext-tools"; then \
dists="$$dists Makevars.template"; \
fi; \
if test -f $(srcdir)/$(DOMAIN).pot; then \
dists="$$dists $(DOMAIN).pot stamp-po"; \
+ else \
+ case $(XGETTEXT) in \
+ :) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because a suitable 'xgettext' program was not found in PATH." 1>&2;; \
+ *) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because 'xgettext' found no strings to extract. Check the contents of the POTFILES.in file and the XGETTEXT_OPTIONS in the Makevars file." 1>&2;; \
+ esac; \
fi; \
if test -f $(srcdir)/ChangeLog; then \
dists="$$dists ChangeLog"; \
@@ -471,13 +464,15 @@
tmpdir=`pwd`; \
echo "$$lang:"; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang --previous $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
cd $(srcdir); \
if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].*) \
$(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ 0.1[6-7] | 0.1[6-7].*) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
*) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
esac; \
}; then \
if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
@@ -504,10 +499,9 @@
# because execution permission bits may not work on the current file system.
# Use @SHELL@, which is the shell determined by autoconf for the use by its
# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
-# Note: Fixed missging 'srcdir', Modified to fit MHD needs
-Makefile: $(srcdir)/Makefile.in.in $(srcdir)/Makevars $(top_po_builddir)/config.status @POMAKEFILEDEPS@
- cd $(top_po_builddir) \
- && @SHELL@ ./config.status ./$@.in po-directories
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && @SHELL@ ./config.status $(subdir)/$@.in po-directories
force:
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/Makevars
^
|
@@ -1,4 +1,8 @@
# Makefile variables for PO directory in any package using GNU gettext.
+#
+# Copyright (C) 2003-2019 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to use, copy, distribute, and modify it.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
@@ -18,7 +22,7 @@
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
-COPYRIGHT_HOLDER = Christian Grothoff
+COPYRIGHT_HOLDER = Free Software Foundation, Inc.
# This tells whether or not to prepend "GNU " prefix to the package
# name that gets inserted into the header of the $(DOMAIN).pot file.
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/POTFILES.in
^
|
@@ -0,0 +1,41 @@
+src/include/microhttpd.h
+src/microhttpd/base64.h
+src/microhttpd/mhd_mono_clock.h
+src/microhttpd/tsearch.h
+src/microhttpd/connection_https.c
+src/microhttpd/reason_phrase.c
+src/microhttpd/mhd_itc_types.h
+src/microhttpd/sysfdsetsize.h
+src/microhttpd/mhd_threads.h
+src/microhttpd/mhd_sockets.c
+src/microhttpd/mhd_threads.c
+src/microhttpd/mhd_str.h
+src/microhttpd/mhd_compat.c
+src/microhttpd/tsearch.c
+src/microhttpd/internal.c
+src/microhttpd/mhd_byteorder.h
+src/microhttpd/mhd_locks.h
+src/microhttpd/memorypool.h
+src/microhttpd/memorypool.c
+src/microhttpd/connection.h
+src/microhttpd/internal.h
+src/microhttpd/digestauth.c
+src/microhttpd/sysfdsetsize.c
+src/microhttpd/md5.h
+src/microhttpd/postprocessor.c
+src/microhttpd/response.h
+src/microhttpd/mhd_str.c
+src/microhttpd/daemon.c
+src/microhttpd/mhd_assert.h
+src/microhttpd/mhd_mono_clock.c
+src/microhttpd/base64.c
+src/microhttpd/md5.c
+src/microhttpd/mhd_sockets.h
+src/microhttpd/mhd_compat.h
+src/microhttpd/connection.c
+src/microhttpd/response.c
+src/microhttpd/mhd_itc.h
+src/microhttpd/connection_https.h
+src/microhttpd/mhd_limits.h
+src/microhttpd/mhd_itc.c
+src/microhttpd/basicauth.c
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/Rules-quot
^
|
@@ -1,5 +1,9 @@
-# This file, Rules-quot, can be copied and used freely without restrictions.
# Special Makefile rules for English message catalogs with quotation marks.
+#
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# This file, Rules-quot, and its auxiliary files (listed under
+# DISTFILES.common.extra1) are free software; the Free Software Foundation
+# gives unlimited permission to use, copy, distribute, and modify them.
DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/aclocal.m4
^
|
@@ -0,0 +1,1161 @@
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.15.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([../m4/gettext.m4])
+m4_include([../m4/iconv.m4])
+m4_include([../m4/intlmacosx.m4])
+m4_include([../m4/lib-ld.m4])
+m4_include([../m4/lib-link.m4])
+m4_include([../m4/lib-prefix.m4])
+m4_include([../m4/nls.m4])
+m4_include([../m4/po.m4])
+m4_include([../m4/progtest.m4])
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/config.status
^
|
@@ -0,0 +1,1204 @@
+#! /bin/sh
+# Generated by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by GNU Libmicrohttpd $as_me 0.9.59, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+# Files that config.status was made for.
+config_files=" ./Makefile.in"
+config_commands=" po-directories depfiles"
+
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to <libmicrohttpd@gnu.org>.
+GNU Libmicrohttpd home page: <http://www.gnu.org/software/libmicrohttpd/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+
+ac_cs_config="'--prefix=/home/grothoff/' 'CFLAGS=-g -Wall -O0' '--srcdir=/home/grothoff/research/libmicrohttpd/po' '--disable-option-checking'"
+ac_cs_version="\
+GNU Libmicrohttpd config.status 0.9.59
+configured by /home/grothoff/research/libmicrohttpd/po/configure, generated by GNU Autoconf 2.69,
+ with options \"$ac_cs_config\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='/home/grothoff/research/libmicrohttpd/po'
+srcdir='.'
+INSTALL='/usr/bin/install -c'
+MKDIR_P='/bin/mkdir -p'
+AWK='gawk'
+test -n "$AWK" || AWK=awk
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+if $ac_cs_recheck; then
+ set X /bin/sh '/home/grothoff/research/libmicrohttpd/po/configure' '--prefix=/home/grothoff/' 'CFLAGS=-g -Wall -O0' '--srcdir=/home/grothoff/research/libmicrohttpd/po' '--disable-option-checking' $ac_configure_extra_args --no-create --no-recursion
+ shift
+ $as_echo "running CONFIG_SHELL=/bin/sh $*" >&6
+ CONFIG_SHELL='/bin/sh'
+ export CONFIG_SHELL
+ exec "$@"
+fi
+
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+#
+# INIT-COMMANDS
+#
+# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake < 1.5.
+ eval 'OBSOLETE_ALL_LINGUAS''=""'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="%UNSET%"
+
+AMDEP_TRUE="" ac_aux_dir=".."
+
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "./Makefile.in") CONFIG_FILES="$CONFIG_FILES ./Makefile.in" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+cat >>"$ac_tmp/subs1.awk" <<\_ACAWK &&
+S["am__EXEEXT_FALSE"]=""
+S["am__EXEEXT_TRUE"]="#"
+S["LTLIBOBJS"]=""
+S["LIBOBJS"]=""
+S["POSUB"]="po"
+S["LTLIBINTL"]=""
+S["LIBINTL"]=""
+S["INTLLIBS"]=""
+S["LTLIBICONV"]="-liconv"
+S["LIBICONV"]="-liconv"
+S["INTL_MACOSX_LIBS"]=""
+S["EGREP"]="/bin/grep -E"
+S["GREP"]="/bin/grep"
+S["CPP"]="gcc -E"
+S["host_os"]="linux-gnu"
+S["host_vendor"]="pc"
+S["host_cpu"]="x86_64"
+S["host"]="x86_64-pc-linux-gnu"
+S["build_os"]="linux-gnu"
+S["build_vendor"]="pc"
+S["build_cpu"]="x86_64"
+S["build"]="x86_64-pc-linux-gnu"
+S["am__fastdepCC_FALSE"]="#"
+S["am__fastdepCC_TRUE"]=""
+S["CCDEPMODE"]="depmode=gcc3"
+S["am__nodep"]="_no"
+S["AMDEPBACKSLASH"]="\\"
+S["AMDEP_FALSE"]="#"
+S["AMDEP_TRUE"]=""
+S["am__quote"]=""
+S["am__include"]="include"
+S["DEPDIR"]=".deps"
+S["OBJEXT"]="o"
+S["EXEEXT"]=""
+S["ac_ct_CC"]="gcc"
+S["CPPFLAGS"]=""
+S["LDFLAGS"]=""
+S["CFLAGS"]="-g -Wall -O0"
+S["CC"]="gcc"
+S["XGETTEXT_EXTRA_OPTIONS"]=""
+S["MSGMERGE"]="/usr/bin/msgmerge"
+S["XGETTEXT_015"]="/usr/bin/xgettext"
+S["XGETTEXT"]="/usr/bin/xgettext"
+S["GMSGFMT_015"]="/usr/bin/msgfmt"
+S["MSGFMT_015"]="/usr/bin/msgfmt"
+S["GMSGFMT"]="/usr/bin/msgfmt"
+S["MSGFMT"]="/usr/bin/msgfmt"
+S["GETTEXT_MACRO_VERSION"]="0.19"
+S["USE_NLS"]="yes"
+S["SED"]="/bin/sed"
+S["AM_BACKSLASH"]="\\"
+S["AM_DEFAULT_VERBOSITY"]="1"
+S["AM_DEFAULT_V"]="$(AM_DEFAULT_VERBOSITY)"
+S["AM_V"]="$(V)"
+S["am__untar"]="$${TAR-tar} xf -"
+S["am__tar"]="$${TAR-tar} chof - \"$$tardir\""
+S["AMTAR"]="$${TAR-tar}"
+S["am__leading_dot"]="."
+S["SET_MAKE"]=""
+S["AWK"]="gawk"
+S["mkdir_p"]="$(MKDIR_P)"
+S["MKDIR_P"]="/bin/mkdir -p"
+S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s"
+S["STRIP"]=""
+S["install_sh"]="${SHELL} /home/grothoff/research/libmicrohttpd/install-sh"
+S["MAKEINFO"]="${SHELL} /home/grothoff/research/libmicrohttpd/missing makeinfo"
+S["AUTOHEADER"]="${SHELL} /home/grothoff/research/libmicrohttpd/missing autoheader"
+S["AUTOMAKE"]="${SHELL} /home/grothoff/research/libmicrohttpd/missing automake-1.15"
+S["AUTOCONF"]="${SHELL} /home/grothoff/research/libmicrohttpd/missing autoconf"
+S["ACLOCAL"]="${SHELL} /home/grothoff/research/libmicrohttpd/missing aclocal-1.15"
+S["VERSION"]="0.9.59"
+S["PACKAGE"]="libmicrohttpd"
+S["CYGPATH_W"]="echo"
+S["am__isrc"]=""
+S["INSTALL_DATA"]="${INSTALL} -m 644"
+S["INSTALL_SCRIPT"]="${INSTALL}"
+S["INSTALL_PROGRAM"]="${INSTALL}"
+S["target_alias"]=""
+S["host_alias"]=""
+S["build_alias"]=""
+S["LIBS"]=""
+S["ECHO_T"]=""
+S["ECHO_N"]="-n"
+S["ECHO_C"]=""
+S["DEFS"]="-DPACKAGE_NAME=\\\"GNU\\ Libmicrohttpd\\\" -DPACKAGE_TARNAME=\\\"libmicrohttpd\\\" -DPACKAGE_VERSION=\\\"0.9.59\\\" -DPACKAGE_STRING=\\\"GNU\\ Libmicrohttpd\\ 0.9.59"\
+"\\\" -DPACKAGE_BUGREPORT=\\\"libmicrohttpd@gnu.org\\\" -DPACKAGE_URL=\\\"http://www.gnu.org/software/libmicrohttpd/\\\" -DPACKAGE=\\\"libmicrohttpd\\\" -DVERSION="\
+"\\\"0.9.59\\\" -DENABLE_NLS=1 -DHAVE_GETTEXT=1 -DHAVE_DCGETTEXT=1"
+S["mandir"]="${datarootdir}/man"
+S["localedir"]="${datarootdir}/locale"
+S["libdir"]="${exec_prefix}/lib"
+S["psdir"]="${docdir}"
+S["pdfdir"]="${docdir}"
+S["dvidir"]="${docdir}"
+S["htmldir"]="${docdir}"
+S["infodir"]="${datarootdir}/info"
+S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}"
+S["oldincludedir"]="/usr/include"
+S["includedir"]="${prefix}/include"
+S["runstatedir"]="${localstatedir}/run"
+S["localstatedir"]="${prefix}/var"
+S["sharedstatedir"]="${prefix}/com"
+S["sysconfdir"]="${prefix}/etc"
+S["datadir"]="${datarootdir}"
+S["datarootdir"]="${prefix}/share"
+S["libexecdir"]="${exec_prefix}/libexec"
+S["sbindir"]="${exec_prefix}/sbin"
+S["bindir"]="${exec_prefix}/bin"
+S["program_transform_name"]="s,x,x,"
+S["prefix"]="/home/grothoff"
+S["exec_prefix"]="${prefix}"
+S["PACKAGE_URL"]="http://www.gnu.org/software/libmicrohttpd/"
+S["PACKAGE_BUGREPORT"]="libmicrohttpd@gnu.org"
+S["PACKAGE_STRING"]="GNU Libmicrohttpd 0.9.59"
+S["PACKAGE_VERSION"]="0.9.59"
+S["PACKAGE_TARNAME"]="libmicrohttpd"
+S["PACKAGE_NAME"]="GNU Libmicrohttpd"
+S["PATH_SEPARATOR"]=":"
+S["SHELL"]="/bin/sh"
+_ACAWK
+cat >>"$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+ ac_datarootdir_hack='
+ s&@datadir@&${datarootdir}&g
+ s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g
+ s&@infodir@&${datarootdir}/info&g
+ s&@localedir@&${datarootdir}/locale&g
+ s&@mandir@&${datarootdir}/man&g
+ s&\${datarootdir}&${prefix}/share&g' ;;
+esac
+ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}
+
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "po-directories":C)
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ gt_tab=`printf '\t'`
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assignment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done ;;
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/configure.ac
^
|
@@ -0,0 +1,17 @@
+# This configure.ac.in is in the public domain
+
+# Use versions from parent configure
+AC_INIT([GNU Libmicrohttpd], [0.9.59], [libmicrohttpd@gnu.org])
+
+AC_CONFIG_SRCDIR([Makevars])
+AC_CONFIG_MACRO_DIR([../m4])
+AC_CONFIG_AUX_DIR([..])
+AM_INIT_AUTOMAKE([silent-rules])
+
+AM_GNU_GETTEXT([external])
+
+# gettext expect that 'po' files will stay in subdirectory.
+# Form './Makefile.in' is accepted by gettext as subdirectory but caused some
+# troubles with in-place build (with relative path to source files). To workaround
+# this, some hack are used in Makefile.
+AC_OUTPUT([./Makefile.in])
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/libmicrohttpd.pot
^
|
@@ -0,0 +1,955 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# This file is distributed under the same license as the GNU libmicrohttpd package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU libmicrohttpd 0.9.73\n"
+"Report-Msgid-Bugs-To: libmicrohttpd@gnu.org\n"
+"POT-Creation-Date: 2021-04-24 21:59+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/microhttpd/connection_https.c:161
+msgid "Error: received handshake message out of context.\n"
+msgstr ""
+
+#: src/microhttpd/mhd_locks.h:125
+msgid "Failed to destroy mutex.\n"
+msgstr ""
+
+#: src/microhttpd/mhd_locks.h:158
+msgid "Failed to lock mutex.\n"
+msgstr ""
+
+#: src/microhttpd/mhd_locks.h:184
+msgid "Failed to unlock mutex.\n"
+msgstr ""
+
+#: src/microhttpd/internal.h:96
+msgid "Failed to close FD.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:605
+msgid ""
+"Stale nonce received. If this happens a lot, you should probably increase "
+"the size of the nonce array.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:807
+msgid "Failed to allocate memory for copy of URI arguments.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:951
+msgid "Authentication failed, invalid timestamp format.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1013
+msgid "Authentication failed, invalid format.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1023
+msgid "Authentication failed, invalid nc format.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1049
+msgid "Failed to allocate memory for auth header processing.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1109
+msgid "Authentication failed, URI does not match.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1128
+msgid "Authentication failed, arguments do not match.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1289
+msgid "Digest size mismatch.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1382
+msgid "Could not register nonce (is the nonce array size zero?).\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1407
+msgid "Failed to allocate memory for auth response header.\n"
+msgstr ""
+
+#: src/microhttpd/digestauth.c:1449
+msgid "Failed to add Digest auth header.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:136
+#, c-format
+msgid "Fatal error in GNU libmicrohttpd %s:%u: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:449
+msgid "Failed to add IP connection count node.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:507
+msgid "Failed to find previously-added IP address.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:513
+msgid "Previously-added IP address had counter of zero.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:565
+msgid "Too long trust certificate.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:577
+msgid "Bad trust certificate format.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:602
+msgid "Too long key or certificate.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:623
+msgid ""
+"Failed to setup x509 certificate/key: pre 3.X.X version of GnuTLS does not "
+"support setting key password.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:637
+#, c-format
+msgid "GnuTLS failed to setup x509 certificate/key: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:652
+msgid "You need to specify a certificate and key location.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:682
+#, c-format
+msgid "Error: invalid credentials type %d specified.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1086
+#, c-format
+msgid "Maximum socket in select set: %d\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1147
+msgid ""
+"MHD_get_fdset2() called with except_fd_set set to NULL. Such behavior is "
+"unsupported.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1361 src/microhttpd/daemon.c:7387
+msgid ""
+"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1375 src/microhttpd/daemon.c:1613
+msgid "Failed to forward to application "
+msgstr ""
+
+#: src/microhttpd/daemon.c:1543 src/microhttpd/daemon.c:1669
+msgid "Failed to forward to remote client "
+msgstr ""
+
+#: src/microhttpd/daemon.c:1739
+msgid "Error preparing select.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1774 src/microhttpd/daemon.c:1929
+#: src/microhttpd/daemon.c:2073
+#, c-format
+msgid "Error during select (%d): `%s'\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1824 src/microhttpd/daemon.c:1950
+#: src/microhttpd/daemon.c:2142
+#, c-format
+msgid "Error during poll: `%s'\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:1913 src/microhttpd/daemon.c:2055
+msgid "Failed to add FD to fd_set.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2195
+msgid "Processing thread terminating. Closing connection.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2225
+msgid ""
+"Failed to signal thread termination via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2305
+msgid "Internal server error. This should be impossible.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2315 src/microhttpd/daemon.c:2353
+msgid "PSK not supported by this server.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2330
+msgid "PSK authentication failed: gnutls_malloc failed to allocate memory.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2339
+msgid "PSK authentication failed: PSK too long.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2401
+#, c-format
+msgid "Accepted connection on socket %d.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2414 src/microhttpd/daemon.c:2745
+msgid "Server reached connection limit. Closing inbound connection.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2432
+msgid "Connection rejected by application. Closing connection.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2450 src/microhttpd/daemon.c:2478
+#: src/microhttpd/daemon.c:2718 src/microhttpd/daemon.c:4310
+#, c-format
+msgid "Error allocating memory: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2546
+msgid "Failed to initialise TLS session.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2572
+msgid "Failed to set ALPN protocols.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2600
+#, c-format
+msgid "Failed to setup TLS credentials: unknown credential type %d.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2610
+msgid "Unknown credential type.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2637
+msgid "TLS connection on non-TLS daemon.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2783
+#, c-format
+msgid "Failed to create a thread: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2809 src/microhttpd/daemon.c:4821
+#: src/microhttpd/daemon.c:4854 src/microhttpd/daemon.c:6208
+#: src/microhttpd/daemon.c:6227 src/microhttpd/connection.c:3870
+#: src/microhttpd/response.c:1236 src/microhttpd/response.c:1262
+#, c-format
+msgid "Call to epoll_ctl failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2920
+#, c-format
+msgid ""
+"New connection socket descriptor (%d) is not less than FD_SETSIZE (%d).\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2937
+msgid "Epoll mode supports only non-blocking sockets\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:2974
+msgid ""
+"Failed to signal new connection via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3019
+msgid "Failed to start serving new connection.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3092 src/microhttpd/daemon.c:3745
+#: src/microhttpd/daemon.c:7254 src/microhttpd/connection.c:759
+#: src/microhttpd/connection.c:778
+msgid "Failed to remove FD from epoll set.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3148
+msgid "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3155
+msgid "Error: connection scheduled for \"upgrade\" cannot be suspended.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3179
+msgid "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3194
+msgid "Failed to signal resume via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3334
+msgid ""
+"Failed to signal resume of connection via inter-thread communication "
+"channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3388
+msgid ""
+"MHD_add_connection() has been called for daemon started without MHD_USE_ITC "
+"flag.\n"
+"Daemon will not process newly added connection until any activity occurs in "
+"already added sockets.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3399
+#, c-format
+msgid "Failed to set nonblocking mode on new client socket: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3418
+#, c-format
+msgid "Failed to suppress SIGPIPE on new client socket: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3444
+msgid "Failed to set noninheritable mode on new client socket.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3567
+#, c-format
+msgid "Error accepting connection: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3585
+msgid ""
+"Hit process or system resource limit at FIRST connection. This is really bad "
+"as there is no sane way to proceed. Will try busy waiting for system "
+"resources to become magically available.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3600
+#, c-format
+msgid ""
+"Hit process or system resource limit at %u connections, temporarily "
+"suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3613
+#, c-format
+msgid "Failed to set nonblocking mode on incoming connection socket: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3626
+msgid "Failed to set noninheritable mode on incoming connection socket.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3636
+#, c-format
+msgid "Failed to suppress SIGPIPE on incoming connection socket: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3657
+#, c-format
+msgid "Accepted connection on socket %d\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3702 src/microhttpd/daemon.c:7428
+#: src/microhttpd/daemon.c:7460 src/microhttpd/daemon.c:7493
+#: src/microhttpd/daemon.c:7599
+msgid "Failed to join a thread.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:3811
+msgid "Illegal call to MHD_get_timeout.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4039
+msgid ""
+"MHD_run_from_select() called with except_fd_set set to NULL. Such behavior "
+"is deprecated.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4120
+msgid "Could not obtain daemon fdsets.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4137
+msgid "Could not add listen socket to fdset.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4166
+msgid "Could not add control inter-thread communication channel FD to fdset.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4246
+#, c-format
+msgid "select failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4386 src/microhttpd/daemon.c:4540
+#, c-format
+msgid "poll failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4683 src/microhttpd/daemon.c:4908
+#, c-format
+msgid "Call to epoll_wait failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:4873 src/microhttpd/daemon.c:5410
+msgid "Failed to remove listen FD from epoll set.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5255
+#, c-format
+msgid "Failed to block SIGPIPE on daemon thread: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5391
+msgid "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5419
+msgid "Failed to signal quiesce via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5442
+msgid "failed to signal quiesce via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5559
+msgid "Warning: Too large timeout value, ignored.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5604
+msgid ""
+"Warning: Zero size, specified for thread pool size, is ignored. Thread pool "
+"is not used.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5613
+msgid ""
+"Warning: \"1\", specified for thread pool size, is ignored. Thread pool is "
+"not used.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5627
+#, c-format
+msgid "Specified thread pool size (%u) too big.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5639
+msgid ""
+"MHD_OPTION_THREAD_POOL_SIZE option is specified but "
+"MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5648
+msgid ""
+"Both MHD_OPTION_THREAD_POOL_SIZE option and MHD_USE_THREAD_PER_CONNECTION "
+"flag are specified.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5666 src/microhttpd/daemon.c:5679
+#: src/microhttpd/daemon.c:5692 src/microhttpd/daemon.c:5705
+#: src/microhttpd/daemon.c:5757 src/microhttpd/daemon.c:5786
+#: src/microhttpd/daemon.c:5807 src/microhttpd/daemon.c:5829
+#: src/microhttpd/daemon.c:6097
+#, c-format
+msgid "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5725
+msgid "Error initializing DH parameters.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5735
+msgid "Diffie-Hellman parameters string too long.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5746
+msgid "Bad Diffie-Hellman parameters format.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5774
+#, c-format
+msgid "Setting priorities to `%s' failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5795
+msgid ""
+"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5817
+msgid ""
+"MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5852
+msgid ""
+"MHD_OPTION_LISTEN_SOCKET specified for daemon with MHD_USE_NO_LISTEN_SOCKET "
+"flag set.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5890
+msgid ""
+"MHD_OPTION_EXTERNAL_LOGGER is not the first option specified for the daemon. "
+"Some messages may be printed by the standard MHD logger.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5915
+msgid "TCP fastopen is not supported on this platform.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:5934
+msgid ""
+"Flag MHD_USE_PEDANTIC_CHECKS is ignored because another behavior is "
+"specified by MHD_OPTION_STRICT_CLIENT.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6072
+#, c-format
+msgid "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6111
+#, c-format
+msgid "MHD HTTPS option %d passed to MHD compiled without HTTPS support.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6118
+#, c-format
+msgid "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?).\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6148
+#, c-format
+msgid "Call to epoll_create1 failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6158
+msgid "Failed to set noninheritable mode on epoll FD.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6465
+msgid ""
+"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
+"MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD was "
+"added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6478
+msgid "Using debug build of libmicrohttpd.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6492
+#, c-format
+msgid "Failed to create inter-thread communication channel: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6509
+msgid ""
+"file descriptor for inter-thread communication channel exceeds maximum "
+"value.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6529
+msgid "Specified value for NC_SIZE too large.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6543
+#, c-format
+msgid "Failed to allocate memory for nonce-nc map: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6560
+msgid "MHD failed to initialize nonce-nc mutex.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6581
+msgid "MHD thread polling only works with MHD_USE_INTERNAL_POLLING_THREAD.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6605
+#, c-format
+msgid "Failed to create socket for listening: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6626 src/microhttpd/daemon.c:6645
+#: src/microhttpd/daemon.c:6668 src/microhttpd/daemon.c:6706
+#: src/microhttpd/daemon.c:6783 src/microhttpd/daemon.c:6814
+#, c-format
+msgid "setsockopt failed: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6679
+msgid "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6715
+msgid ""
+"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6794
+#, c-format
+msgid "Failed to bind to port %u: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6825
+#, c-format
+msgid "Failed to listen for connections: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6856
+#, c-format
+msgid "Failed to get listen port number: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6867
+msgid ""
+"Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6908
+msgid "Unknown address family!\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6921
+#, c-format
+msgid "Failed to set nonblocking mode on listening socket: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6944
+#, c-format
+msgid "Listen socket descriptor (%d) is not less than FD_SETSIZE (%d).\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6965
+msgid ""
+"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:6979 src/microhttpd/daemon.c:6989
+msgid "MHD failed to initialize IP connection limit mutex.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7007
+msgid "Failed to initialize TLS support.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7040 src/microhttpd/daemon.c:7105
+#: src/microhttpd/daemon.c:7204
+msgid "Failed to initialise mutex.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7058
+#, c-format
+msgid "Failed to create listen thread: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7116
+#, c-format
+msgid "Failed to create worker inter-thread communication channel: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7129
+msgid ""
+"File descriptor for worker inter-thread communication channel exceeds "
+"maximum value.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7167
+msgid "MHD failed to initialize cleanup connection mutex.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7184
+#, c-format
+msgid "Failed to create pool thread: %s\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7373 src/microhttpd/daemon.c:7406
+msgid "MHD_stop_daemon() called while we have suspended connections.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7445 src/microhttpd/daemon.c:7543
+#: src/microhttpd/daemon.c:7581
+msgid "Failed to signal shutdown via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:7518
+msgid "MHD_stop_daemon() was called twice."
+msgstr ""
+
+#: src/microhttpd/daemon.c:8031
+msgid "Failed to initialize winsock.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:8034
+msgid "Winsock version 2.2 is not available.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:8042 src/microhttpd/daemon.c:8046
+msgid "Failed to initialise multithreading in libgcrypt.\n"
+msgstr ""
+
+#: src/microhttpd/daemon.c:8052
+msgid "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"
+msgstr ""
+
+#: src/microhttpd/mhd_sockets.h:333
+msgid "Close socket failed.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:140
+msgid "The operation would block, retry later"
+msgstr ""
+
+#: src/microhttpd/connection.c:142
+msgid "The connection was forcibly closed by remote peer"
+msgstr ""
+
+#: src/microhttpd/connection.c:144
+msgid "The socket is not connected"
+msgstr ""
+
+#: src/microhttpd/connection.c:146
+msgid "Not enough system resources to serve the request"
+msgstr ""
+
+#: src/microhttpd/connection.c:148
+msgid "Bad FD value"
+msgstr ""
+
+#: src/microhttpd/connection.c:150
+msgid "Argument value is invalid"
+msgstr ""
+
+#: src/microhttpd/connection.c:152
+msgid "Argument value is not supported"
+msgstr ""
+
+#: src/microhttpd/connection.c:154
+msgid "The socket is no longer available for sending"
+msgstr ""
+
+#: src/microhttpd/connection.c:156
+msgid "TLS encryption or decryption error"
+msgstr ""
+
+#: src/microhttpd/connection.c:161
+msgid "Not an error code"
+msgstr ""
+
+#: src/microhttpd/connection.c:164
+msgid "Wrong error code value"
+msgstr ""
+
+#: src/microhttpd/connection.c:868 src/microhttpd/connection.c:962
+msgid "Closing connection (out of memory)."
+msgstr ""
+
+#: src/microhttpd/connection.c:913
+msgid "Closing connection (application reported error generating data)."
+msgstr ""
+
+#: src/microhttpd/connection.c:1010
+msgid "Closing connection (application error generating response)."
+msgstr ""
+
+#: src/microhttpd/connection.c:1653
+#, c-format
+msgid ""
+"Error processing request (HTTP response code is %u (`%s')). Closing "
+"connection.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:1680 src/microhttpd/connection.c:2722
+msgid "Closing connection (failed to queue response)."
+msgstr ""
+
+#: src/microhttpd/connection.c:1691 src/microhttpd/connection.c:3708
+msgid "Closing connection (failed to create response header)."
+msgstr ""
+
+#: src/microhttpd/connection.c:1737 src/microhttpd/connection.c:2888
+#: src/microhttpd/connection.c:2956 src/microhttpd/connection.c:3372
+#, c-format
+msgid "In function %s handling connection at state: %s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:1955
+msgid "Not enough memory in pool to allocate header record!\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2002
+msgid "Not enough memory in pool to parse cookies!\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2233 src/microhttpd/connection.c:2437
+msgid "Application reported internal error, closing connection."
+msgstr ""
+
+#: src/microhttpd/connection.c:2302 src/microhttpd/connection.c:2381
+msgid ""
+"Received malformed HTTP request (bad chunked encoding). Closing connection."
+msgstr ""
+
+#: src/microhttpd/connection.c:2445
+msgid "libmicrohttpd API violation.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2461
+msgid ""
+"WARNING: incomplete upload processing and connection not suspended may "
+"result in hung connection.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2535
+msgid "Received malformed line (no colon). Closing connection."
+msgstr ""
+
+#: src/microhttpd/connection.c:2698
+msgid "Received HTTP 1.1 request without `Host' header.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2710
+msgid "Closing connection (failed to create response)."
+msgstr ""
+
+#: src/microhttpd/connection.c:2760
+msgid "Failed to parse `Content-Length' header. Closing connection.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2861
+msgid "Socket disconnected while reading request."
+msgstr ""
+
+#: src/microhttpd/connection.c:2868
+#, c-format
+msgid "Connection socket is closed when reading request due to the error: %s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2983
+#, c-format
+msgid "Failed to send data in request for %s.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:2992
+#, c-format
+msgid "Sent 100 continue response: `%.*s'\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3063
+#, c-format
+msgid ""
+"Failed to send the response headers for the request for `%s'. Error: %s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3128
+msgid "Data offset exceeds limit.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3138
+#, c-format
+msgid "Sent %d-byte DATA response: `%.*s'\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3155
+#, c-format
+msgid "Failed to send the response body for the request for `%s'. Error: %s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3187
+#, c-format
+msgid ""
+"Failed to send the chunked response body for the request for `%s'. Error: "
+"%s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3223
+#, c-format
+msgid "Failed to send the footers for the request for `%s'. Error: %s\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3252
+msgid "Internal error.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3330
+msgid ""
+"Failed to signal end of connection via inter-thread communication channel.\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:3599
+msgid "Closing connection (failed to create response header).\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:4060
+msgid "Attempted to queue response on wrong thread!\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:4072
+msgid ""
+"Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"
+msgstr ""
+
+#: src/microhttpd/connection.c:4082
+msgid "Application used invalid status code for 'upgrade' response!\n"
+msgstr ""
+
+#: src/microhttpd/response.c:1096
+msgid ""
+"Invalid response for upgrade: application failed to set the 'Upgrade' "
+"header!\n"
+msgstr ""
+
+#: src/microhttpd/response.c:1139
+msgid "Failed to make loopback sockets non-blocking.\n"
+msgstr ""
+
+#: src/microhttpd/response.c:1158
+msgid "Failed to set SO_NOSIGPIPE on loopback sockets.\n"
+msgstr ""
+
+#: src/microhttpd/response.c:1178
+#, c-format
+msgid "Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"
+msgstr ""
+
+#: src/microhttpd/response.c:1259
+msgid "Error cleaning up while handling epoll error.\n"
+msgstr ""
+
+#: src/microhttpd/mhd_itc.h:355
+msgid "Failed to destroy ITC.\n"
+msgstr ""
+
+#: src/microhttpd/basicauth.c:71
+msgid "Error decoding basic authentication.\n"
+msgstr ""
+
+#: src/microhttpd/basicauth.c:81
+msgid "Basic authentication doesn't contain ':' separator.\n"
+msgstr ""
+
+#: src/microhttpd/basicauth.c:99
+msgid "Failed to allocate memory for password.\n"
+msgstr ""
+
+#: src/microhttpd/basicauth.c:164
+msgid "Failed to add Basic auth header.\n"
+msgstr ""
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/remove-potcdate.sin
^
|
@@ -1,6 +1,12 @@
-# Sed script that remove the POT-Creation-Date line in the header entry
+# Sed script that removes the POT-Creation-Date line in the header entry
# from a POT file.
#
+# Copyright (C) 2002 Free Software Foundation, Inc.
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without any warranty.
+#
# The distinction between the first and the following occurrences of the
# pattern is achieved by looking at the hold space.
/^"POT-Creation-Date: .*"$/{
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/po/stamp-po
^
|
@@ -0,0 +1 @@
+timestamp
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/Makefile.am
^
|
@@ -14,6 +14,13 @@
SUBDIRS += examples
endif
+# Finally (last!) also build experimental lib...
+if HAVE_EXPERIMENTAL
+SUBDIRS += lib
+endif
+
EXTRA_DIST = \
datadir/cert-and-key.pem \
datadir/cert-and-key-for-wireshark.pem
+
+.NOTPARALLEL:
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/.gitignore
^
|
@@ -32,3 +32,9 @@
/https_echo_client_example.c
/authorization_example
upgrade_example
+websocket_threaded_example
+/timeout
+http_chunked_compression
+http_compression
+minimal_example_empty
+minimal_example_empty_tls
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/Makefile.am
^
|
@@ -7,7 +7,7 @@
AM_CFLAGS = @LIBGCRYPT_CFLAGS@
-CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT)
+MHD_CPU_COUNT_DEF = -DMHD_CPU_COUNT=$(CPU_COUNT)
if USE_COVERAGE
AM_CFLAGS += --coverage
@@ -20,6 +20,7 @@
benchmark_https \
chunked_example \
minimal_example \
+ minimal_example_empty \
dual_stack_example \
minimal_example_comet \
querystring_example \
@@ -29,19 +30,27 @@
fileserver_example_external_select \
refuse_post_example
+if MHD_HAVE_EPOLL
+noinst_PROGRAMS += \
+ suspend_resume_epoll
+endif
+
EXTRA_DIST = msgs_i18n.c
noinst_EXTRA_DIST = msgs_i18n.c
if ENABLE_HTTPS
-noinst_PROGRAMS += https_fileserver_example
+noinst_PROGRAMS += \
+ https_fileserver_example \
+ minimal_example_empty_tls
endif
if HAVE_POSTPROCESSOR
noinst_PROGRAMS += \
post_example
-if HAVE_MAGIC
-noinst_PROGRAMS += \
- demo \
- demo_https
+if HAVE_POSIX_THREADS
+noinst_PROGRAMS += demo
+if ENABLE_HTTPS
+noinst_PROGRAMS += demo_https
+endif
endif
endif
@@ -55,9 +64,18 @@
authorization_example
endif
+if HAVE_POSIX_THREADS
if ENABLE_UPGRADE
noinst_PROGRAMS += \
- upgrade_example
+ upgrade_example \
+ websocket_threaded_example
+endif
+endif
+
+if HAVE_ZLIB
+noinst_PROGRAMS += \
+ http_compression \
+ http_chunked_compression
endif
if HAVE_W32
@@ -69,10 +87,31 @@
minimal_example_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
+minimal_example_empty_SOURCES = \
+ minimal_example_empty.c
+minimal_example_empty_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+minimal_example_empty_tls_SOURCES = \
+ minimal_example_empty_tls.c
+minimal_example_empty_tls_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
upgrade_example_SOURCES = \
upgrade_example.c
+upgrade_example_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
upgrade_example_LDADD = \
- $(top_builddir)/src/microhttpd/libmicrohttpd.la
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS)
+
+websocket_threaded_example_SOURCES = \
+ websocket_threaded_example.c
+websocket_threaded_example_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+websocket_threaded_example_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS)
timeout_SOURCES = \
timeout.c
@@ -89,32 +128,45 @@
demo_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
demo_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
demo_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(PTHREAD_LIBS) -lmagic
+ $(PTHREAD_LIBS)
+if HAVE_LIBMAGIC
+demo_LDADD += -lmagic
+endif
demo_https_SOURCES = \
demo_https.c
demo_https_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
demo_https_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
demo_https_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(PTHREAD_LIBS) -lmagic
+ $(PTHREAD_LIBS)
+if HAVE_LIBMAGIC
+demo_https_LDADD += -lmagic
+endif
benchmark_SOURCES = \
benchmark.c
benchmark_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
benchmark_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
+suspend_resume_epoll_SOURCES = \
+ suspend_resume_epoll.c
+suspend_resume_epoll_CPPFLAGS = \
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
+suspend_resume_epoll_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
benchmark_https_SOURCES = \
benchmark_https.c
benchmark_https_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
benchmark_https_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
@@ -174,3 +226,16 @@
$(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
https_fileserver_example_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+http_compression_SOURCES = \
+ http_compression.c
+http_chunked_compression_SOURCES = \
+ http_chunked_compression.c
+http_compression_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+http_chunked_compression_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+if HAVE_ZLIB
+ http_compression_LDADD += -lz
+ http_chunked_compression_LDADD += -lz
+endif
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/authorization_example.c
^
|
@@ -32,13 +32,14 @@
#include <windows.h>
#endif
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
-#define DENIED "<html><head><title>Access denied</title></head><body>Access denied</body></html>"
+#define DENIED \
+ "<html><head><title>Access denied</title></head><body>Access denied</body></html>"
-
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -49,43 +50,50 @@
static int aptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
char *user;
char *pass;
int fail;
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
/* require: "Aladdin" with password "open sesame" */
pass = NULL;
- user = MHD_basic_auth_get_username_password (connection, &pass);
- fail = ( (user == NULL) || (0 != strcmp (user, "Aladdin")) || (0 != strcmp (pass, "open sesame") ) );
+ user = MHD_basic_auth_get_username_password (connection,
+ &pass);
+ fail = ( (NULL == user) ||
+ (0 != strcmp (user, "Aladdin")) ||
+ (0 != strcmp (pass, "open sesame") ) );
if (fail)
{
- response = MHD_create_response_from_buffer (strlen (DENIED),
- (void *) DENIED,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_basic_auth_fail_response (connection,"TestRealm",response);
- }
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ (void *) DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_basic_auth_fail_response (connection,"TestRealm",response);
+ }
else
- {
- response = MHD_create_response_from_buffer (strlen (me),
- (void *) me,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (me),
+ (void *) me,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ }
if (NULL != user)
- free (user);
+ MHD_free (user);
if (NULL != pass)
- free (pass);
+ MHD_free (pass);
MHD_destroy_response (response);
return ret;
}
@@ -100,18 +108,19 @@
if ( (argc != 2) ||
(1 != sscanf (argv[1], "%u", &port)) ||
(UINT16_MAX < port) )
- {
- fprintf (stderr,
- "%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ fprintf (stderr,
+ "%s PORT\n", argv[0]);
+ return 1;
+ }
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
if (d == NULL)
return 1;
- fprintf (stderr, "HTTP server running. Press ENTER to stop the server\n");
+ fprintf (stderr, "HTTP server running. Press ENTER to stop the server.\n");
(void) getc (stdin);
MHD_stop_daemon (d);
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/benchmark.c
^
|
@@ -25,14 +25,15 @@
#include "platform.h"
#include <microhttpd.h>
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
#define SMALL (1024 * 128)
@@ -41,14 +42,13 @@
* Number of threads to run in the thread pool. Should (roughly) match
* the number of cores on your system.
*/
-#define NUMBER_OF_THREADS CPU_COUNT
+#define NUMBER_OF_THREADS MHD_CPU_COUNT
static unsigned int small_deltas[SMALL];
static struct MHD_Response *response;
-
/**
* Signature of the callback used by MHD to notify the
* application about completed requests.
@@ -62,13 +62,16 @@
*/
static void
completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct timeval *tv = *con_cls;
struct timeval tve;
uint64_t delta;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == tv)
return;
@@ -77,10 +80,10 @@
delta = 0;
if (tve.tv_usec >= tv->tv_usec)
delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
- + (tve.tv_usec - tv->tv_usec);
+ + (tve.tv_usec - tv->tv_usec);
else
delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
- - tv->tv_usec + tve.tv_usec;
+ - tv->tv_usec + tve.tv_usec;
if (delta < SMALL)
small_deltas[delta]++;
else
@@ -91,9 +94,11 @@
static void *
uri_logger_cb (void *cls,
- const char *uri)
+ const char *uri)
{
struct timeval *tv = malloc (sizeof (struct timeval));
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) uri; /* Unused. Silent compiler warning. */
if (NULL != tv)
gettimeofday (tv, NULL);
@@ -101,7 +106,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -109,6 +114,13 @@
const char *version,
const char *upload_data, size_t *upload_data_size, void **ptr)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) ptr; /* Unused. Silent compiler warning. */
+
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
return MHD_queue_response (connection, MHD_HTTP_OK, response);
@@ -122,37 +134,39 @@
unsigned int i;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
response = MHD_create_response_from_buffer (strlen (PAGE),
- (void *) PAGE,
- MHD_RESPMEM_PERSISTENT);
+ (void *) PAGE,
+ MHD_RESPMEM_PERSISTENT);
#if 0
(void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONNECTION,
- "close");
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
#endif
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_SUPPRESS_DATE_NO_CLOCK
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_SUPPRESS_DATE_NO_CLOCK
#ifdef EPOLL_SUPPORT
- | MHD_USE_EPOLL | MHD_USE_TURBO
+ | MHD_USE_EPOLL | MHD_USE_TURBO
#endif
- ,
+ ,
atoi (argv[1]),
NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
- MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
- MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
- MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned
+ int) NUMBER_OF_THREADS,
+ MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
+ MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
MHD_stop_daemon (d);
MHD_destroy_response (response);
- for (i=0;i<SMALL;i++)
+ for (i = 0; i<SMALL; i++)
if (0 != small_deltas[i])
fprintf (stdout, "D: %d %u\n", i, small_deltas[i]);
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/benchmark_https.c
^
|
@@ -25,14 +25,15 @@
#include "platform.h"
#include <microhttpd.h>
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
#define SMALL (1024 * 128)
@@ -41,14 +42,13 @@
* Number of threads to run in the thread pool. Should (roughly) match
* the number of cores on your system.
*/
-#define NUMBER_OF_THREADS CPU_COUNT
+#define NUMBER_OF_THREADS MHD_CPU_COUNT
static unsigned int small_deltas[SMALL];
static struct MHD_Response *response;
-
/**
* Signature of the callback used by MHD to notify the
* application about completed requests.
@@ -62,13 +62,16 @@
*/
static void
completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct timeval *tv = *con_cls;
struct timeval tve;
uint64_t delta;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == tv)
return;
@@ -77,10 +80,10 @@
delta = 0;
if (tve.tv_usec >= tv->tv_usec)
delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
- + (tve.tv_usec - tv->tv_usec);
+ + (tve.tv_usec - tv->tv_usec);
else
delta += (tve.tv_sec - tv->tv_sec) * 1000000LL
- - tv->tv_usec + tve.tv_usec;
+ - tv->tv_usec + tve.tv_usec;
if (delta < SMALL)
small_deltas[delta]++;
else
@@ -91,9 +94,11 @@
static void *
uri_logger_cb (void *cls,
- const char *uri)
+ const char *uri)
{
struct timeval *tv = malloc (sizeof (struct timeval));
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) uri; /* Unused. Silent compiler warning. */
if (NULL != tv)
gettimeofday (tv, NULL);
@@ -101,7 +106,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -109,6 +114,13 @@
const char *version,
const char *upload_data, size_t *upload_data_size, void **ptr)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) ptr; /* Unused. Silent compiler warning. */
+
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
return MHD_queue_response (connection, MHD_HTTP_OK, response);
@@ -116,54 +128,69 @@
/* test server key */
-const char srv_signed_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEowIBAAKCAQEAvfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW\n"
- "+K03KwEku55QvnUndwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8IL\n"
- "q4sw32vo0fbMu5BZF49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ0\n"
- "20Q5EAAEseD1YtWCIpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6\n"
- "QYGGh1QmHRPAy3CBII6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6x\n"
- "yoOl204xuekZOaG9RUPId74Rtmwfi1TLbBzo2wIDAQABAoIBADu09WSICNq5cMe4\n"
- "+NKCLlgAT1NiQpLls1gKRbDhKiHU9j8QWNvWWkJWrCya4QdUfLCfeddCMeiQmv3K\n"
- "lJMvDs+5OjJSHFoOsGiuW2Ias7IjnIojaJalfBml6frhJ84G27IXmdz6gzOiTIer\n"
- "DjeAgcwBaKH5WwIay2TxIaScl7AwHBauQkrLcyb4hTmZuQh6ArVIN6+pzoVuORXM\n"
- "bpeNWl2l/HSN3VtUN6aCAKbN/X3o0GavCCMn5Fa85uJFsab4ss/uP+2PusU71+zP\n"
- "sBm6p/2IbGvF5k3VPDA7X5YX61sukRjRBihY8xSnNYx1UcoOsX6AiPnbhifD8+xQ\n"
- "Tlf8oJUCgYEA0BTfzqNpr9Wxw5/QXaSdw7S/0eP5a0C/nwURvmfSzuTD4equzbEN\n"
- "d+dI/s2JMxrdj/I4uoAfUXRGaabevQIjFzC9uyE3LaOyR2zhuvAzX+vVcs6bSXeU\n"
- "pKpCAcN+3Z3evMaX2f+z/nfSUAl2i4J2R+/LQAWJW4KwRky/m+cxpfUCgYEA6bN1\n"
- "b73bMgM8wpNt6+fcmS+5n0iZihygQ2U2DEud8nZJL4Nrm1dwTnfZfJBnkGj6+0Q0\n"
- "cOwj2KS0/wcEdJBP0jucU4v60VMhp75AQeHqidIde0bTViSRo3HWKXHBIFGYoU3T\n"
- "LyPyKndbqsOObnsFXHn56Nwhr2HLf6nw4taGQY8CgYBoSW36FLCNbd6QGvLFXBGt\n"
- "2lMhEM8az/K58kJ4WXSwOLtr6MD/WjNT2tkcy0puEJLm6BFCd6A6pLn9jaKou/92\n"
- "SfltZjJPb3GUlp9zn5tAAeSSi7YMViBrfuFiHObij5LorefBXISLjuYbMwL03MgH\n"
- "Ocl2JtA2ywMp2KFXs8GQWQKBgFyIVv5ogQrbZ0pvj31xr9HjqK6d01VxIi+tOmpB\n"
- "4ocnOLEcaxX12BzprW55ytfOCVpF1jHD/imAhb3YrHXu0fwe6DXYXfZV4SSG2vB7\n"
- "IB9z14KBN5qLHjNGFpMQXHSMek+b/ftTU0ZnPh9uEM5D3YqRLVd7GcdUhHvG8P8Q\n"
- "C9aXAoGBAJtID6h8wOGMP0XYX5YYnhlC7dOLfk8UYrzlp3xhqVkzKthTQTj6wx9R\n"
- "GtC4k7U1ki8oJsfcIlBNXd768fqDVWjYju5rzShMpo8OCTS6ipAblKjCxPPVhIpv\n"
- "tWPlbSn1qj6wylstJ5/3Z+ZW5H4wIKp5jmLiioDhcP0L/Ex3Zx8O\n"
- "-----END RSA PRIVATE KEY-----\n";
+const char srv_signed_key_pem[] =
+ "-----BEGIN PRIVATE KEY-----\n\
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrm8uH8V0P2Xbl\n\
+HCMq6PTIphDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZ\n\
+Vyg4ksOA7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd\n\
+6mi978n//bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5yg\n\
+CR99TDDHZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/Lni\n\
+CGO9uXGOgZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF\n\
+1N8GZZC7AgMBAAECggEAc0F/wR3qUurLX7U2KWuse9aNHFb84mBfCAw3hj7ddFEl\n\
+wto7EB50MA0KY4OI8u6fQH4E8zINoAciDzLqYJSxmbZhC1N5YX/Yc3qtZdB2b5tj\n\
+anbsSQqVo8YVPVDU4bCsG9vhArdd4JdCnD0DfA3ArZ3JAPwHsB4Ks1icLSOIGz0/\n\
+JvOZEryJBdwM6SKbzLMqVOGmYDiY6s7UpJ0rg3cOPqhdg5xv8XZATqXISU0mLBcq\n\
+RiS7lHZERASYON2rpznhBiCtikOcr/duQhvZ1uDSGfDzDJil+1hdS3RouS9WZCIe\n\
+p3CtvZhPLmv6kFg9YE+AovDwOOwNr0no3H9oJA2FgQKBgQDSWrE/MRMRpFJFBxxC\n\
+YckC2v8Y+7sVSMbFNq/0j2eRTql+8AeZBbAoGU4QHUcylCBkv33zDYRY52xNo32E\n\
+8mmH2O/pIcYy0LafrVZHdulf+fxybncObidxmmjR9C8aLzwRuIMtABz4simaQcBD\n\
+RhZJ1YCqVkfMr/PlbLzvC8V+FwKBgQDQ2MF/Yz/p7QEDHpfKdtx7+yK6i8IM+V8l\n\
+d2OuscNkQQywCVqE2vyRZJbjU9y+Om7alNKFPhhBzavdOxNWXGXmlBIlvo3v6M++\n\
+fTixza77LxHvbghH0ykplSwGh30vpHtvoxsRS5nRFxmsVK9jNYYT/Aes+J6MXlq7\n\
+PYAiZVQs/QKBgFKYY8JhPZCOyfLqsNDr3matoL6pkTLxSYMETyCi8lKe5XS/QOx3\n\
+zExia0FujZcxjGqiugymgRH7hI4TpOR/3qoFp2YN6enoA908zYTwDwCtgs9Xyo2y\n\
++O/lZkUSMTCB3X9DyNXxlm6cXjOAn8KKkZPaLlQz3qtjZ0vtX14pbBlvAoGBAKw0\n\
+vsCifvYNZhNDa5gXkFBu0MEPMm/uQ+Up37kRfPKyrJqO6+O2iiH81moWIWN93SBB\n\
+LKGPhQLlazxdVOGWCLQrDhevW2wiBQKmUFRULF+T/W72xL8sv7k49ndfyvq43ss7\n\
+q7sEIo4FRTcTERd179uUqmOXEWze9GOGH5y8/r6lAoGAG2YyqRWF+yxKlgR71b1Q\n\
+Zxv53WgXOUwemGRbXxE4g3gHpW5k9zWh4QTkbd0lDD+SQ0DBwZl/x/FWj43jUS+i\n\
+a5UojDUx8nYgjiAO7kppMlX3ZaJD1DkwEz+4HW9oPmOFt8smvuTVt0mm6tpmQdRA\n\
+yLwgQzGDGVJB6ETVJS7cwWs=\n\
+-----END PRIVATE KEY-----";
/* test server CA signed certificates */
-const char srv_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
- "MIIDGzCCAgWgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
- "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
- "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
- "vfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW+K03KwEku55QvnUn\n"
- "dwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8ILq4sw32vo0fbMu5BZ\n"
- "F49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ020Q5EAAEseD1YtWC\n"
- "IpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6QYGGh1QmHRPAy3CB\n"
- "II6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6xyoOl204xuekZOaG9\n"
- "RUPId74Rtmwfi1TLbBzo2wIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
- "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFOFi4ilKOP1d\n"
- "XHlWCMwmVKr7mgy8MB8GA1UdIwQYMBaAFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsG\n"
- "CSqGSIb3DQEBBQOCAQEAHVWPxazupbOkG7Did+dY9z2z6RjTzYvurTtEKQgzM2Vz\n"
- "GQBA+3pZ3c5mS97fPIs9hZXfnQeelMeZ2XP1a+9vp35bJjZBBhVH+pqxjCgiUflg\n"
- "A3Zqy0XwwVCgQLE2HyaU3DLUD/aeIFK5gJaOSdNTXZLv43K8kl4cqDbMeRpVTbkt\n"
- "YmG4AyEOYRNKGTqMEJXJoxD5E3rBUNrVI/XyTjYrulxbNPcMWEHKNeeqWpKDYTFo\n"
- "Bb01PCthGXiq/4A2RLAFosadzRa8SBpoSjPPfZ0b2w4MJpReHqKbR5+T2t6hzml6\n"
- "4ToyOKPDmamiTuN5KzLN3cw7DQlvWMvqSOChPLnA3Q==\n"
- "-----END CERTIFICATE-----\n";
+const char srv_signed_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIFaTCCA1GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MjFaGA8yMTIxMDMxMzE3\n\
+MzYyMVowgYcxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMRQwEgYDVQQDDAt0\n\
+ZXN0LXNlcnZlcjEjMCEGA1UdEQwaRE5TOmxvY2FsaG9zdCxJUDoxMjcuMC4wLjEw\n\
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrm8uH8V0P2XblHCMq6PTI\n\
+phDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZVyg4ksOA\n\
+7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd6mi978n/\n\
+/bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5ygCR99TDDH\n\
+ZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/LniCGO9uXGO\n\
+gZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF1N8GZZC7\n\
+AgMBAAGjgeEwgd4wCwYDVR0PBAQDAgWgMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n\
+BAwwCgYIKwYBBQUHAwEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAA\n\
+AAAAAAAAAAAAAAABMB0GA1UdDgQWBBRifkHd2xWI51NhnH8sL66K8EedpjAoBglg\n\
+hkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBkIHNlcnZlcjARBglghkgBhvhC\n\
+AQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOFNd0arI3/QB3W6SwwDQYJKoZI\n\
+hvcNAQELBQADggIBAJoIyNrnwQ+7WcJDaBjjuwSH0ORuK+E3zRI3+nDde08gyfeG\n\
+K4QozT2L574WzadTVLSiin9lRShYlp0nr60pmUb9+SKE0O7Cx+rYV0Rfu0KLYsYh\n\
+sAkb9J9t1fdIt54fXNcUtvfGPyM2lEI0KxMCGNV2wXDnwzdSNIU6Nk457MntfZdi\n\
+r1ISnS6fLd0BIKIGxfCFb10CexhNOSaExgpp1bxZovdYaQWggL0u8eC8j00sJ1C5\n\
+Qo4gQ1TQsead6zMs6m19TPLlV7hS+hfXj7yeJ/TTUj69bCjTIMp6HCFnfQbD84BI\n\
+HZDKk4Tob9vBRCKbY58kNXHyQ4nxvSCBlKI03VJjvzpsKTI/vW9JBivtnYtMbMl9\n\
+ouZal/IVsNqRCeiMTLky62qrFhZr2DHgPG5VcOGQ4y0X4vOgM9n/MMOGWcNBByLX\n\
+b5ZaYr7DPCcz9dYZgEbwXj8wnuAzM1sJ2igwTmO/vQsn1G2Q/h/JB471CD1avuuI\n\
+awKRqhU2KhYVrwo7ahJkPV9Lm6eoavq2Tu+e1o4qAFhPLMy/6F+bZmK6GfHMvP+L\n\
+v+GOQdUJ/vMMus/HB5N3cUZsu9rGnCCVgPW7pkHrp5bRtuVzBT78ISsxkGnOhfT7\n\
+6Kp7ApvfEX6/Y/vbDFBC4kyAvEIZ+F8AUkbvZ0+k8j5xlarNd6TQ3slEGi6O\n\
+-----END CERTIFICATE-----";
int
@@ -173,34 +200,37 @@
unsigned int i;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
response = MHD_create_response_from_buffer (strlen (PAGE),
- (void *) PAGE,
- MHD_RESPMEM_PERSISTENT);
+ (void *) PAGE,
+ MHD_RESPMEM_PERSISTENT);
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
#ifdef EPOLL_SUPPORT
- | MHD_USE_EPOLL | MHD_USE_TURBO
+ | MHD_USE_EPOLL | MHD_USE_TURBO
#endif
- ,
+ ,
atoi (argv[1]),
NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
- MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
- MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned
+ int) NUMBER_OF_THREADS,
+ MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
+ MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
+ /* Optionally, the gnutls_load_file() can be used to
+ load the key and the certificate from file. */
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
- MHD_OPTION_END);
+ MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
MHD_stop_daemon (d);
MHD_destroy_response (response);
- for (i=0;i<SMALL;i++)
+ for (i = 0; i<SMALL; i++)
if (0 != small_deltas[i])
fprintf (stdout, "D: %d %u\n", i, small_deltas[i]);
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/chunked_example.c
^
|
@@ -20,74 +20,159 @@
* @file chunked_example.c
* @brief example for generating chunked encoding with libmicrohttpd
* @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
*/
#include "platform.h"
#include <microhttpd.h>
+struct ResponseContentCallbackParam
+{
+ const char *response_data;
+ size_t response_size;
+};
+
static ssize_t
callback (void *cls,
uint64_t pos,
char *buf,
- size_t max)
+ size_t buf_size)
+{
+ size_t size_to_copy;
+ struct ResponseContentCallbackParam *const param =
+ (struct ResponseContentCallbackParam *) cls;
+
+ /* Note: 'pos' will never exceed size of transmitted data. */
+ /* You can use 'pos == param->response_size' in next check. */
+ if (pos >= param->response_size)
+ { /* Whole response was sent. Signal end of response. */
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ }
+
+ /* Pseudo code. *
+ if (data_not_ready)
+ {
+ // Callback will be called again on next loop.
+ // Consider suspending connection until data will be ready.
+ return 0;
+ }
+ * End of pseudo code. */
+ if (buf_size < (param->response_size - pos))
+ size_to_copy = buf_size;
+ else
+ size_to_copy = param->response_size - pos;
+
+ memcpy (buf, param->response_data + pos, size_to_copy);
+
+ /* Pseudo code. *
+ if (error_preparing_response)
+ {
+ // Close connection with error.
+ return MHD_CONTENT_READER_END_WITH_ERROR;
+ }
+ * End of pseudo code. */
+ /* Return amount of data copied to buffer. */
+ return size_to_copy;
+}
+
+
+static void
+free_callback_param (void *cls)
{
- return MHD_CONTENT_READER_END_OF_STREAM;
+ free (cls);
}
+static const char simple_response_text[] =
+ "<html><head><title>Simple response</title></head>"
+ "<body>Simple response text</body></html>";
+
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
- const char *upload_data, size_t *upload_data_size, void **ptr)
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
{
static int aptr;
+ struct ResponseContentCallbackParam *callback_param;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+
+ callback_param = malloc (sizeof(struct ResponseContentCallbackParam));
+ if (NULL == callback_param)
+ return MHD_NO; /* Not enough memory. */
+
+ callback_param->response_data = simple_response_text;
+ callback_param->response_size = (sizeof(simple_response_text)
+ / sizeof(char)) - 1;
+
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
1024,
&callback,
- NULL,
- NULL);
+ callback_param,
+ &free_callback_param);
+ if (NULL == response)
+ {
+ free (callback_param);
+ return MHD_NO;
+ }
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
+
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
+ int port;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- // MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- atoi (argv[1]),
- NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_END);
- if (d == NULL)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ port = atoi (argv[1]);
+ if ( (1 > port) ||
+ (port > UINT16_MAX) )
+ {
+ fprintf (stderr,
+ "Port must be a number between 1 and 65535.\n");
+ return 1;
+ }
+ d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ (uint16_t) port,
+ NULL, NULL,
+ &ahc_echo, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_END);
+ if (NULL == d)
return 1;
(void) getc (stdin);
MHD_stop_daemon (d);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/connection_close.c
^
|
@@ -0,0 +1,122 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file connection_close.c
+ * @brief minimal example for connection close notifications
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include <microhttpd.h>
+
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+
+static int
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size, void **ptr)
+{
+ static int aptr;
+ const char *me = cls;
+ struct MHD_Response *response;
+ int ret;
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (method, "GET"))
+ return MHD_NO; /* unexpected method */
+ if (&aptr != *ptr)
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
+ response = MHD_create_response_from_buffer (strlen (me),
+ (void *) me,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+#include <x86intrin.h>
+
+static void
+request_completed (void *cls,
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
+{
+ fprintf (stderr,
+ "%llu - RC: %d\n",
+ (unsigned long long) __rdtsc (),
+ toe);
+}
+
+
+static void
+connection_completed (void *cls,
+ struct MHD_Connection *connection,
+ void **socket_context,
+ enum MHD_ConnectionNotificationCode toe)
+{
+ fprintf (stderr,
+ "%llu - CC: %d\n",
+ (unsigned long long) __rdtsc (),
+ toe);
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ struct MHD_Daemon *d;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ /* MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG | MHD_USE_POLL, // | MHD_USE_ITC,
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, PAGE,
+ MHD_OPTION_NOTIFY_COMPLETED, &request_completed, NULL,
+ MHD_OPTION_NOTIFY_CONNECTION, &connection_completed, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/demo.c
^
|
@@ -35,74 +35,88 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
+#ifdef MHD_HAVE_LIBMAGIC
#include <magic.h>
+#endif /* MHD_HAVE_LIBMAGIC */
#include <limits.h>
#include <ctype.h>
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+#ifndef PATH_MAX
+/* Some platforms (namely: GNU Hurd) do no define PATH_MAX.
+ As it is only example for MHD, just use reasonable value for PATH_MAX. */
+#define PATH_MAX 16384
#endif
/**
* Number of threads to run in the thread pool. Should (roughly) match
* the number of cores on your system.
*/
-#define NUMBER_OF_THREADS CPU_COUNT
+#define NUMBER_OF_THREADS MHD_CPU_COUNT
+#ifdef MHD_HAVE_LIBMAGIC
/**
* How many bytes of a file do we give to libmagic to determine the mime type?
* 16k might be a bit excessive, but ought not hurt performance much anyway,
* and should definitively be on the safe side.
*/
#define MAGIC_HEADER_SIZE (16 * 1024)
+#endif /* MHD_HAVE_LIBMAGIC */
/**
* Page returned for file-not-found.
*/
-#define FILE_NOT_FOUND_PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define FILE_NOT_FOUND_PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
/**
* Page returned for internal errors.
*/
-#define INTERNAL_ERROR_PAGE "<html><head><title>Internal error</title></head><body>Internal error</body></html>"
+#define INTERNAL_ERROR_PAGE \
+ "<html><head><title>Internal error</title></head><body>Internal error</body></html>"
/**
* Page returned for refused requests.
*/
-#define REQUEST_REFUSED_PAGE "<html><head><title>Request refused</title></head><body>Request refused (file exists?)</body></html>"
+#define REQUEST_REFUSED_PAGE \
+ "<html><head><title>Request refused</title></head><body>Request refused (file exists?)</body></html>"
/**
* Head of index page.
*/
-#define INDEX_PAGE_HEADER "<html>\n<head><title>Welcome</title></head>\n<body>\n"\
- "<h1>Upload</h1>\n"\
- "<form method=\"POST\" enctype=\"multipart/form-data\" action=\"/\">\n"\
- "<dl><dt>Content type:</dt><dd>"\
- "<input type=\"radio\" name=\"category\" value=\"books\">Book</input>"\
- "<input type=\"radio\" name=\"category\" value=\"images\">Image</input>"\
- "<input type=\"radio\" name=\"category\" value=\"music\">Music</input>"\
- "<input type=\"radio\" name=\"category\" value=\"software\">Software</input>"\
- "<input type=\"radio\" name=\"category\" value=\"videos\">Videos</input>\n"\
- "<input type=\"radio\" name=\"category\" value=\"other\" checked>Other</input></dd>"\
- "<dt>Language:</dt><dd>"\
- "<input type=\"radio\" name=\"language\" value=\"no-lang\" checked>none</input>"\
- "<input type=\"radio\" name=\"language\" value=\"en\">English</input>"\
- "<input type=\"radio\" name=\"language\" value=\"de\">German</input>"\
- "<input type=\"radio\" name=\"language\" value=\"fr\">French</input>"\
- "<input type=\"radio\" name=\"language\" value=\"es\">Spanish</input></dd>\n"\
- "<dt>File:</dt><dd>"\
- "<input type=\"file\" name=\"upload\"/></dd></dl>"\
- "<input type=\"submit\" value=\"Send!\"/>\n"\
- "</form>\n"\
- "<h1>Download</h1>\n"\
- "<ol>\n"
+#define INDEX_PAGE_HEADER \
+ "<html>\n<head><title>Welcome</title></head>\n<body>\n" \
+ "<h1>Upload</h1>\n" \
+ "<form method=\"POST\" enctype=\"multipart/form-data\" action=\"/\">\n" \
+ "<dl><dt>Content type:</dt><dd>" \
+ "<input type=\"radio\" name=\"category\" value=\"books\">Book</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"images\">Image</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"music\">Music</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"software\">Software</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"videos\">Videos</input>\n" \
+ "<input type=\"radio\" name=\"category\" value=\"other\" checked>Other</input></dd>" \
+ "<dt>Language:</dt><dd>" \
+ "<input type=\"radio\" name=\"language\" value=\"no-lang\" checked>none</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"en\">English</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"de\">German</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"fr\">French</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"es\">Spanish</input></dd>\n" \
+ "<dt>File:</dt><dd>" \
+ "<input type=\"file\" name=\"upload\"/></dd></dl>" \
+ "<input type=\"submit\" value=\"Send!\"/>\n" \
+ "</form>\n" \
+ "<h1>Download</h1>\n" \
+ "<ol>\n"
/**
* Footer of index page.
@@ -114,16 +128,15 @@
* NULL-terminated array of supported upload categories. Should match HTML
* in the form.
*/
-static const char * const categories[] =
- {
- "books",
- "images",
- "music",
- "software",
- "videos",
- "other",
- NULL,
- };
+static const char *const categories[] = {
+ "books",
+ "images",
+ "music",
+ "software",
+ "videos",
+ "other",
+ NULL,
+};
/**
@@ -147,15 +160,14 @@
* NULL-terminated array of supported upload categories. Should match HTML
* in the form.
*/
-static const struct Language languages[] =
- {
- { "no-lang", "No language specified" },
- { "en", "English" },
- { "de", "German" },
- { "fr", "French" },
- { "es", "Spanish" },
- { NULL, NULL },
- };
+static const struct Language languages[] = {
+ { "no-lang", "No language specified" },
+ { "en", "English" },
+ { "de", "German" },
+ { "fr", "French" },
+ { "es", "Spanish" },
+ { NULL, NULL },
+};
/**
@@ -183,14 +195,16 @@
*/
static pthread_mutex_t mutex;
+#ifdef MHD_HAVE_LIBMAGIC
/**
* Global handle to MAGIC data.
*/
static magic_t magic;
+#endif /* MHD_HAVE_LIBMAGIC */
/**
- * Mark the given response as HTML for the brower.
+ * Mark the given response as HTML for the browser.
*
* @param response response to mark
*/
@@ -198,8 +212,8 @@
mark_as_html (struct MHD_Response *response)
{
(void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html");
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html");
}
@@ -248,11 +262,11 @@
*
* @param rdc where to store the list of files
* @param dirname name of the directory to list
- * @return MHD_YES on success, MHD_NO on error
+ * @return #MHD_YES on success, #MHD_NO on error
*/
-static int
+static enum MHD_Result
list_directory (struct ResponseDataContext *rdc,
- const char *dirname)
+ const char *dirname)
{
char fullname[PATH_MAX];
struct stat sbuf;
@@ -262,35 +276,35 @@
if (NULL == (dir = opendir (dirname)))
return MHD_NO;
while (NULL != (de = readdir (dir)))
- {
- if ('.' == de->d_name[0])
- continue;
- if (sizeof (fullname) <= (size_t)
- snprintf (fullname, sizeof (fullname),
- "%s/%s",
- dirname, de->d_name))
- continue; /* ugh, file too long? how can this be!? */
- if (0 != stat (fullname, &sbuf))
- continue; /* ugh, failed to 'stat' */
- if (! S_ISREG (sbuf.st_mode))
- continue; /* not a regular file, skip */
- if (rdc->off + 1024 > rdc->buf_len)
- {
- void *r;
-
- if ( (2 * rdc->buf_len + 1024) < rdc->buf_len)
- break; /* more than SIZE_T _index_ size? Too big for us */
- rdc->buf_len = 2 * rdc->buf_len + 1024;
- if (NULL == (r = realloc (rdc->buf, rdc->buf_len)))
- break; /* out of memory */
- rdc->buf = r;
- }
- rdc->off += snprintf (&rdc->buf[rdc->off],
- rdc->buf_len - rdc->off,
- "<li><a href=\"/%s\">%s</a></li>\n",
- fullname,
- de->d_name);
- }
+ {
+ if ('.' == de->d_name[0])
+ continue;
+ if (sizeof (fullname) <= (unsigned int)
+ snprintf (fullname, sizeof (fullname),
+ "%s/%s",
+ dirname, de->d_name))
+ continue; /* ugh, file too long? how can this be!? */
+ if (0 != stat (fullname, &sbuf))
+ continue; /* ugh, failed to 'stat' */
+ if (! S_ISREG (sbuf.st_mode))
+ continue; /* not a regular file, skip */
+ if (rdc->off + 1024 > rdc->buf_len)
+ {
+ void *r;
+
+ if ( (2 * rdc->buf_len + 1024) < rdc->buf_len)
+ break; /* more than SIZE_T _index_ size? Too big for us */
+ rdc->buf_len = 2 * rdc->buf_len + 1024;
+ if (NULL == (r = realloc (rdc->buf, rdc->buf_len)))
+ break; /* out of memory */
+ rdc->buf = r;
+ }
+ rdc->off += snprintf (&rdc->buf[rdc->off],
+ rdc->buf_len - rdc->off,
+ "<li><a href=\"/%s\">%s</a></li>\n",
+ fullname,
+ de->d_name);
+ }
(void) closedir (dir);
return MHD_YES;
}
@@ -314,65 +328,66 @@
rdc.buf_len = initial_allocation;
if (NULL == (rdc.buf = malloc (rdc.buf_len)))
- {
- update_cached_response (NULL);
- return;
- }
+ {
+ update_cached_response (NULL);
+ return;
+ }
rdc.off = snprintf (rdc.buf, rdc.buf_len,
- "%s",
- INDEX_PAGE_HEADER);
- for (language_idx = 0; NULL != languages[language_idx].dirname; language_idx++)
- {
- language = &languages[language_idx];
+ "%s",
+ INDEX_PAGE_HEADER);
+ for (language_idx = 0; NULL != languages[language_idx].dirname;
+ language_idx++)
+ {
+ language = &languages[language_idx];
+
+ if (0 != stat (language->dirname, &sbuf))
+ continue; /* empty */
+ /* we ensured always +1k room, filenames are ~256 bytes,
+ so there is always still enough space for the header
+ without need for an additional reallocation check. */
+ rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
+ "<h2>%s</h2>\n",
+ language->longname);
+ for (category_idx = 0; NULL != categories[category_idx]; category_idx++)
+ {
+ category = categories[category_idx];
+ snprintf (dir_name, sizeof (dir_name),
+ "%s/%s",
+ language->dirname,
+ category);
+ if (0 != stat (dir_name, &sbuf))
+ continue; /* empty */
- if (0 != stat (language->dirname, &sbuf))
- continue; /* empty */
/* we ensured always +1k room, filenames are ~256 bytes,
- so there is always still enough space for the header
- without need for an additional reallocation check. */
+ so there is always still enough space for the header
+ without need for an additional reallocation check. */
rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "<h2>%s</h2>\n",
- language->longname);
- for (category_idx = 0; NULL != categories[category_idx]; category_idx++)
- {
- category = categories[category_idx];
- snprintf (dir_name, sizeof (dir_name),
- "%s/%s",
- language->dirname,
- category);
- if (0 != stat (dir_name, &sbuf))
- continue; /* empty */
-
- /* we ensured always +1k room, filenames are ~256 bytes,
- so there is always still enough space for the header
- without need for an additional reallocation check. */
- rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "<h3>%s</h3>\n",
- category);
-
- if (MHD_NO == list_directory (&rdc, dir_name))
- {
- free (rdc.buf);
- update_cached_response (NULL);
- return;
- }
- }
+ "<h3>%s</h3>\n",
+ category);
+
+ if (MHD_NO == list_directory (&rdc, dir_name))
+ {
+ free (rdc.buf);
+ update_cached_response (NULL);
+ return;
+ }
}
+ }
/* we ensured always +1k room, filenames are ~256 bytes,
so there is always still enough space for the footer
without need for a final reallocation check. */
rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "%s",
- INDEX_PAGE_FOOTER);
+ "%s",
+ INDEX_PAGE_FOOTER);
initial_allocation = rdc.buf_len; /* remember for next time */
response = MHD_create_response_from_buffer (rdc.off,
- rdc.buf,
- MHD_RESPMEM_MUST_FREE);
+ rdc.buf,
+ MHD_RESPMEM_MUST_FREE);
mark_as_html (response);
#if FORCE_CLOSE
(void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONNECTION,
- "close");
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
#endif
update_cached_response (response);
}
@@ -427,12 +442,12 @@
* @param ret string to update, NULL or 0-terminated
* @param data data to append
* @param size number of bytes in 'data'
- * @return MHD_NO on allocation failure, MHD_YES on success
+ * @return #MHD_NO on allocation failure, #MHD_YES on success
*/
-static int
+static enum MHD_Result
do_append (char **ret,
- const char *data,
- size_t size)
+ const char *data,
+ size_t size)
{
char *buf;
size_t old_len;
@@ -441,13 +456,18 @@
old_len = 0;
else
old_len = strlen (*ret);
- buf = malloc (old_len + size + 1);
- if (NULL == buf)
+ if (NULL == (buf = malloc (old_len + size + 1)))
return MHD_NO;
- memcpy (buf, *ret, old_len);
if (NULL != *ret)
+ {
+ memcpy (buf,
+ *ret,
+ old_len);
free (*ret);
- memcpy (&buf[old_len], data, size);
+ }
+ memcpy (&buf[old_len],
+ data,
+ size);
buf[old_len + size] = '\0';
*ret = buf;
return MHD_YES;
@@ -470,120 +490,124 @@
* specified offset
* @param off offset of data in the overall value
* @param size number of bytes in data available
- * @return MHD_YES to continue iterating,
- * MHD_NO to abort the iteration
+ * @return #MHD_YES to continue iterating,
+ * #MHD_NO to abort the iteration
*/
-static int
+static enum MHD_Result
process_upload_data (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *filename,
- const char *content_type,
- const char *transfer_encoding,
- const char *data,
- uint64_t off,
- size_t size)
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
{
struct UploadContext *uc = cls;
int i;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
+ (void) off; /* Unused. Silent compiler warning. */
if (0 == strcmp (key, "category"))
return do_append (&uc->category, data, size);
if (0 == strcmp (key, "language"))
return do_append (&uc->language, data, size);
if (0 != strcmp (key, "upload"))
- {
- fprintf (stderr,
- "Ignoring unexpected form value `%s'\n",
- key);
- return MHD_YES; /* ignore */
- }
+ {
+ fprintf (stderr,
+ "Ignoring unexpected form value `%s'\n",
+ key);
+ return MHD_YES; /* ignore */
+ }
if (NULL == filename)
- {
- fprintf (stderr, "No filename, aborting upload\n");
- return MHD_NO; /* no filename, error */
- }
+ {
+ fprintf (stderr, "No filename, aborting upload.\n");
+ return MHD_NO; /* no filename, error */
+ }
if ( (NULL == uc->category) ||
(NULL == uc->language) )
+ {
+ fprintf (stderr,
+ "Missing form data for upload `%s'\n",
+ filename);
+ uc->response = request_refused_response;
+ return MHD_NO;
+ }
+ if (-1 == uc->fd)
+ {
+ char fn[PATH_MAX];
+
+ if ( (NULL != strstr (filename, "..")) ||
+ (NULL != strchr (filename, '/')) ||
+ (NULL != strchr (filename, '\\')) )
{
- fprintf (stderr,
- "Missing form data for upload `%s'\n",
- filename);
uc->response = request_refused_response;
return MHD_NO;
}
- if (-1 == uc->fd)
- {
- char fn[PATH_MAX];
-
- if ( (NULL != strstr (filename, "..")) ||
- (NULL != strchr (filename, '/')) ||
- (NULL != strchr (filename, '\\')) )
- {
- uc->response = request_refused_response;
- return MHD_NO;
- }
- /* create directories -- if they don't exist already */
+ /* create directories -- if they don't exist already */
#ifdef WINDOWS
- (void) mkdir (uc->language);
+ (void) mkdir (uc->language);
#else
- (void) mkdir (uc->language, S_IRWXU);
+ (void) mkdir (uc->language, S_IRWXU);
#endif
- snprintf (fn, sizeof (fn),
- "%s/%s",
- uc->language,
- uc->category);
+ snprintf (fn, sizeof (fn),
+ "%s/%s",
+ uc->language,
+ uc->category);
#ifdef WINDOWS
- (void) mkdir (fn);
+ (void) mkdir (fn);
#else
- (void) mkdir (fn, S_IRWXU);
+ (void) mkdir (fn, S_IRWXU);
#endif
- /* open file */
- snprintf (fn, sizeof (fn),
- "%s/%s/%s",
- uc->language,
- uc->category,
- filename);
- for (i=strlen (fn)-1;i>=0;i--)
- if (! isprint ((int) fn[i]))
- fn[i] = '_';
- uc->fd = open (fn,
- O_CREAT | O_EXCL
+ /* open file */
+ snprintf (fn, sizeof (fn),
+ "%s/%s/%s",
+ uc->language,
+ uc->category,
+ filename);
+ for (i = strlen (fn) - 1; i>=0; i--)
+ if (! isprint ((unsigned char) fn[i]))
+ fn[i] = '_';
+ uc->fd = open (fn,
+ O_CREAT | O_EXCL
#if O_LARGEFILE
- | O_LARGEFILE
+ | O_LARGEFILE
#endif
- | O_WRONLY,
- S_IRUSR | S_IWUSR);
- if (-1 == uc->fd)
- {
- fprintf (stderr,
- "Error opening file `%s' for upload: %s\n",
- fn,
- strerror (errno));
- uc->response = request_refused_response;
- return MHD_NO;
- }
- uc->filename = strdup (fn);
+ | O_WRONLY,
+ S_IRUSR | S_IWUSR);
+ if (-1 == uc->fd)
+ {
+ fprintf (stderr,
+ "Error opening file `%s' for upload: %s\n",
+ fn,
+ strerror (errno));
+ uc->response = request_refused_response;
+ return MHD_NO;
}
+ uc->filename = strdup (fn);
+ }
if ( (0 != size) &&
(size != (size_t) write (uc->fd, data, size)) )
+ {
+ /* write failed; likely: disk full */
+ fprintf (stderr,
+ "Error writing to file `%s': %s\n",
+ uc->filename,
+ strerror (errno));
+ uc->response = internal_error_response;
+ (void) close (uc->fd);
+ uc->fd = -1;
+ if (NULL != uc->filename)
{
- /* write failed; likely: disk full */
- fprintf (stderr,
- "Error writing to file `%s': %s\n",
- uc->filename,
- strerror (errno));
- uc->response = internal_error_response;
- (void) close (uc->fd);
- uc->fd = -1;
- if (NULL != uc->filename)
- {
- unlink (uc->filename);
- free (uc->filename);
- uc->filename = NULL;
- }
- return MHD_NO;
+ unlink (uc->filename);
+ free (uc->filename);
+ uc->filename = NULL;
}
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -601,29 +625,32 @@
*/
static void
response_completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct UploadContext *uc = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == uc)
return; /* this request wasn't an upload request */
if (NULL != uc->pp)
- {
- MHD_destroy_post_processor (uc->pp);
- uc->pp = NULL;
- }
+ {
+ MHD_destroy_post_processor (uc->pp);
+ uc->pp = NULL;
+ }
if (-1 != uc->fd)
{
(void) close (uc->fd);
if (NULL != uc->filename)
- {
- fprintf (stderr,
- "Upload of file `%s' failed (incomplete or aborted), removing file.\n",
- uc->filename);
- (void) unlink (uc->filename);
- }
+ {
+ fprintf (stderr,
+ "Upload of file `%s' failed (incomplete or aborted), removing file.\n",
+ uc->filename);
+ (void) unlink (uc->filename);
+ }
}
if (NULL != uc->filename)
free (uc->filename);
@@ -635,22 +662,22 @@
* Return the current directory listing.
*
* @param connection connection to return the directory for
- * @return MHD_YES on success, MHD_NO on error
+ * @return #MHD_YES on success, #MHD_NO on error
*/
-static int
+static enum MHD_Result
return_directory_response (struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
(void) pthread_mutex_lock (&mutex);
if (NULL == cached_directory_response)
ret = MHD_queue_response (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- internal_error_response);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ internal_error_response);
else
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- cached_directory_response);
+ MHD_HTTP_OK,
+ cached_directory_response);
(void) pthread_mutex_unlock (&mutex);
return ret;
}
@@ -665,132 +692,138 @@
* @param method GET, PUT, POST, etc.
* @param version HTTP version
* @param upload_data data from upload (PUT/POST)
- * @param upload_data_size number of bytes in "upload_data"
+ * @param upload_data_size number of bytes in @a upload_data
* @param ptr our context
- * @return MHD_YES on success, MHD_NO to drop connection
+ * @return #MHD_YES on success, #MHD_NO to drop connection
*/
-static int
+static enum MHD_Result
generate_page (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size, void **ptr)
{
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int fd;
struct stat buf;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
if (0 != strcmp (url, "/"))
+ {
+ /* should be file download */
+#ifdef MHD_HAVE_LIBMAGIC
+ char file_data[MAGIC_HEADER_SIZE];
+ ssize_t got;
+#endif /* MHD_HAVE_LIBMAGIC */
+ const char *mime;
+
+ if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
+ (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)) )
+ return MHD_NO; /* unexpected method (we're not polite...) */
+ fd = -1;
+ if ( (NULL == strstr (&url[1], "..")) &&
+ ('/' != url[1]) )
+ {
+ fd = open (&url[1], O_RDONLY);
+ if ( (-1 != fd) &&
+ ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) ) )
+ {
+ (void) close (fd);
+ fd = -1;
+ }
+ }
+ if (-1 == fd)
+ return MHD_queue_response (connection,
+ MHD_HTTP_NOT_FOUND,
+ file_not_found_response);
+#ifdef MHD_HAVE_LIBMAGIC
+ /* read beginning of the file to determine mime type */
+ got = read (fd, file_data, sizeof (file_data));
+ (void) lseek (fd, 0, SEEK_SET);
+ if (-1 != got)
+ mime = magic_buffer (magic, file_data, got);
+ else
+#endif /* MHD_HAVE_LIBMAGIC */
+ mime = NULL;
+
+ if (NULL == (response = MHD_create_response_from_fd (buf.st_size,
+ fd)))
{
- /* should be file download */
- char file_data[MAGIC_HEADER_SIZE];
- ssize_t got;
- const char *mime;
-
- if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
- (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)) )
- return MHD_NO; /* unexpected method (we're not polite...) */
- fd = -1;
- if ( (NULL == strstr (&url[1], "..")) &&
- ('/' != url[1]) )
- {
- fd = open (&url[1], O_RDONLY);
- if ( (-1 != fd) &&
- ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) ) )
- {
- (void) close (fd);
- fd = -1;
- }
- }
- if (-1 == fd)
- return MHD_queue_response (connection,
- MHD_HTTP_NOT_FOUND,
- file_not_found_response);
- /* read beginning of the file to determine mime type */
- got = read (fd, file_data, sizeof (file_data));
- if (-1 != got)
- mime = magic_buffer (magic, file_data, got);
- else
- mime = NULL;
- (void) lseek (fd, 0, SEEK_SET);
-
- if (NULL == (response = MHD_create_response_from_fd (buf.st_size,
- fd)))
- {
- /* internal error (i.e. out of memory) */
- (void) close (fd);
- return MHD_NO;
- }
-
- /* add mime type if we had one */
- if (NULL != mime)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- mime);
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- return ret;
+ /* internal error (i.e. out of memory) */
+ (void) close (fd);
+ return MHD_NO;
}
+ /* add mime type if we had one */
+ if (NULL != mime)
+ (void) MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ mime);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+ }
+
if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
- {
- /* upload! */
- struct UploadContext *uc = *ptr;
+ {
+ /* upload! */
+ struct UploadContext *uc = *ptr;
- if (NULL == uc)
- {
- if (NULL == (uc = malloc (sizeof (struct UploadContext))))
- return MHD_NO; /* out of memory, close connection */
- memset (uc, 0, sizeof (struct UploadContext));
- uc->fd = -1;
- uc->connection = connection;
- uc->pp = MHD_create_post_processor (connection,
- 64 * 1024 /* buffer size */,
- &process_upload_data, uc);
- if (NULL == uc->pp)
- {
- /* out of memory, close connection */
- free (uc);
- return MHD_NO;
- }
- *ptr = uc;
- return MHD_YES;
- }
- if (0 != *upload_data_size)
- {
- if (NULL == uc->response)
- (void) MHD_post_process (uc->pp,
- upload_data,
- *upload_data_size);
- *upload_data_size = 0;
- return MHD_YES;
- }
- /* end of upload, finish it! */
- MHD_destroy_post_processor (uc->pp);
- uc->pp = NULL;
- if (-1 != uc->fd)
- {
- close (uc->fd);
- uc->fd = -1;
- }
- if (NULL != uc->response)
- {
- return MHD_queue_response (connection,
- MHD_HTTP_FORBIDDEN,
- uc->response);
- }
- else
- {
- update_directory ();
- return return_directory_response (connection);
- }
+ if (NULL == uc)
+ {
+ if (NULL == (uc = malloc (sizeof (struct UploadContext))))
+ return MHD_NO; /* out of memory, close connection */
+ memset (uc, 0, sizeof (struct UploadContext));
+ uc->fd = -1;
+ uc->connection = connection;
+ uc->pp = MHD_create_post_processor (connection,
+ 64 * 1024 /* buffer size */,
+ &process_upload_data, uc);
+ if (NULL == uc->pp)
+ {
+ /* out of memory, close connection */
+ free (uc);
+ return MHD_NO;
+ }
+ *ptr = uc;
+ return MHD_YES;
}
+ if (0 != *upload_data_size)
+ {
+ if (NULL == uc->response)
+ (void) MHD_post_process (uc->pp,
+ upload_data,
+ *upload_data_size);
+ *upload_data_size = 0;
+ return MHD_YES;
+ }
+ /* end of upload, finish it! */
+ MHD_destroy_post_processor (uc->pp);
+ uc->pp = NULL;
+ if (-1 != uc->fd)
+ {
+ close (uc->fd);
+ uc->fd = -1;
+ }
+ if (NULL != uc->response)
+ {
+ return MHD_queue_response (connection,
+ MHD_HTTP_FORBIDDEN,
+ uc->response);
+ }
+ else
+ {
+ update_directory ();
+ return return_directory_response (connection);
+ }
+ }
if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
(0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
{
@@ -799,11 +832,12 @@
/* unexpected request, refuse */
return MHD_queue_response (connection,
- MHD_HTTP_FORBIDDEN,
- request_refused_response);
+ MHD_HTTP_FORBIDDEN,
+ request_refused_response);
}
+#ifndef MINGW
/**
* Function called if we get a SIGPIPE. Does nothing.
*
@@ -812,6 +846,7 @@
static void
catcher (int sig)
{
+ (void) sig; /* Unused. Silent compiler warning. */
/* do nothing */
}
@@ -819,7 +854,6 @@
/**
* setup handlers to ignore SIGPIPE.
*/
-#ifndef MINGW
static void
ignore_sigpipe ()
{
@@ -837,6 +871,8 @@
fprintf (stderr,
"Failed to install SIGPIPE handler: %s\n", strerror (errno));
}
+
+
#endif
@@ -858,46 +894,59 @@
if ( (argc != 2) ||
(1 != sscanf (argv[1], "%u", &port)) ||
(UINT16_MAX < port) )
- {
- fprintf (stderr,
- "%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ fprintf (stderr,
+ "%s PORT\n", argv[0]);
+ return 1;
+ }
#ifndef MINGW
ignore_sigpipe ();
#endif
+#ifdef MHD_HAVE_LIBMAGIC
magic = magic_open (MAGIC_MIME_TYPE);
(void) magic_load (magic, NULL);
+#endif /* MHD_HAVE_LIBMAGIC */
(void) pthread_mutex_init (&mutex, NULL);
- file_not_found_response = MHD_create_response_from_buffer (strlen (FILE_NOT_FOUND_PAGE),
- (void *) FILE_NOT_FOUND_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ file_not_found_response = MHD_create_response_from_buffer (strlen (
+ FILE_NOT_FOUND_PAGE),
+ (void *)
+ FILE_NOT_FOUND_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (file_not_found_response);
- request_refused_response = MHD_create_response_from_buffer (strlen (REQUEST_REFUSED_PAGE),
- (void *) REQUEST_REFUSED_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ request_refused_response = MHD_create_response_from_buffer (strlen (
+ REQUEST_REFUSED_PAGE),
+ (void *)
+ REQUEST_REFUSED_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (request_refused_response);
- internal_error_response = MHD_create_response_from_buffer (strlen (INTERNAL_ERROR_PAGE),
- (void *) INTERNAL_ERROR_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ internal_error_response = MHD_create_response_from_buffer (strlen (
+ INTERNAL_ERROR_PAGE),
+ (void *)
+ INTERNAL_ERROR_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (internal_error_response);
update_directory ();
- d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG,
port,
NULL, NULL,
- &generate_page, NULL,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024),
+ &generate_page, NULL,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256
+ * 1024),
#if PRODUCTION
- MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
+ MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
#endif
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) (120 /* seconds */),
- MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
- MHD_OPTION_NOTIFY_COMPLETED, &response_completed_callback, NULL,
- MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned
+ int) (120 /* seconds */),
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned
+ int) NUMBER_OF_THREADS,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ &response_completed_callback, NULL,
+ MHD_OPTION_END);
if (NULL == d)
return 1;
- fprintf (stderr, "HTTP server running. Press ENTER to stop the server\n");
+ fprintf (stderr, "HTTP server running. Press ENTER to stop the server.\n");
(void) getc (stdin);
MHD_stop_daemon (d);
MHD_destroy_response (file_not_found_response);
@@ -905,8 +954,11 @@
MHD_destroy_response (internal_error_response);
update_cached_response (NULL);
(void) pthread_mutex_destroy (&mutex);
+#ifdef MHD_HAVE_LIBMAGIC
magic_close (magic);
+#endif /* MHD_HAVE_LIBMAGIC */
return 0;
}
+
/* end of demo.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/demo_https.c
^
|
@@ -27,6 +27,8 @@
* run tests against. Note that the number of threads may need
* to be adjusted depending on the number of available cores.
* Logic is identical to demo.c, just adds HTTPS support.
+ * This demonstration uses key/cert stored in static string. Optionally,
+ * use gnutls_load_file() to load them from file.
* @author Christian Grothoff
*/
#include "platform.h"
@@ -36,74 +38,88 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
+#ifdef MHD_HAVE_LIBMAGIC
#include <magic.h>
+#endif /* MHD_HAVE_LIBMAGIC */
#include <limits.h>
#include <ctype.h>
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+#ifndef PATH_MAX
+/* Some platforms (namely: GNU Hurd) do no define PATH_MAX.
+ As it is only example for MHD, just use reasonable value for PATH_MAX. */
+#define PATH_MAX 16384
#endif
/**
* Number of threads to run in the thread pool. Should (roughly) match
* the number of cores on your system.
*/
-#define NUMBER_OF_THREADS CPU_COUNT
+#define NUMBER_OF_THREADS MHD_CPU_COUNT
+#ifdef MHD_HAVE_LIBMAGIC
/**
* How many bytes of a file do we give to libmagic to determine the mime type?
* 16k might be a bit excessive, but ought not hurt performance much anyway,
* and should definitively be on the safe side.
*/
#define MAGIC_HEADER_SIZE (16 * 1024)
+#endif /* MHD_HAVE_LIBMAGIC */
/**
* Page returned for file-not-found.
*/
-#define FILE_NOT_FOUND_PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define FILE_NOT_FOUND_PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
/**
* Page returned for internal errors.
*/
-#define INTERNAL_ERROR_PAGE "<html><head><title>Internal error</title></head><body>Internal error</body></html>"
+#define INTERNAL_ERROR_PAGE \
+ "<html><head><title>Internal error</title></head><body>Internal error</body></html>"
/**
* Page returned for refused requests.
*/
-#define REQUEST_REFUSED_PAGE "<html><head><title>Request refused</title></head><body>Request refused (file exists?)</body></html>"
+#define REQUEST_REFUSED_PAGE \
+ "<html><head><title>Request refused</title></head><body>Request refused (file exists?)</body></html>"
/**
* Head of index page.
*/
-#define INDEX_PAGE_HEADER "<html>\n<head><title>Welcome</title></head>\n<body>\n"\
- "<h1>Upload</h1>\n"\
- "<form method=\"POST\" enctype=\"multipart/form-data\" action=\"/\">\n"\
- "<dl><dt>Content type:</dt><dd>"\
- "<input type=\"radio\" name=\"category\" value=\"books\">Book</input>"\
- "<input type=\"radio\" name=\"category\" value=\"images\">Image</input>"\
- "<input type=\"radio\" name=\"category\" value=\"music\">Music</input>"\
- "<input type=\"radio\" name=\"category\" value=\"software\">Software</input>"\
- "<input type=\"radio\" name=\"category\" value=\"videos\">Videos</input>\n"\
- "<input type=\"radio\" name=\"category\" value=\"other\" checked>Other</input></dd>"\
- "<dt>Language:</dt><dd>"\
- "<input type=\"radio\" name=\"language\" value=\"no-lang\" checked>none</input>"\
- "<input type=\"radio\" name=\"language\" value=\"en\">English</input>"\
- "<input type=\"radio\" name=\"language\" value=\"de\">German</input>"\
- "<input type=\"radio\" name=\"language\" value=\"fr\">French</input>"\
- "<input type=\"radio\" name=\"language\" value=\"es\">Spanish</input></dd>\n"\
- "<dt>File:</dt><dd>"\
- "<input type=\"file\" name=\"upload\"/></dd></dl>"\
- "<input type=\"submit\" value=\"Send!\"/>\n"\
- "</form>\n"\
- "<h1>Download</h1>\n"\
- "<ol>\n"
+#define INDEX_PAGE_HEADER \
+ "<html>\n<head><title>Welcome</title></head>\n<body>\n" \
+ "<h1>Upload</h1>\n" \
+ "<form method=\"POST\" enctype=\"multipart/form-data\" action=\"/\">\n" \
+ "<dl><dt>Content type:</dt><dd>" \
+ "<input type=\"radio\" name=\"category\" value=\"books\">Book</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"images\">Image</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"music\">Music</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"software\">Software</input>" \
+ "<input type=\"radio\" name=\"category\" value=\"videos\">Videos</input>\n" \
+ "<input type=\"radio\" name=\"category\" value=\"other\" checked>Other</input></dd>" \
+ "<dt>Language:</dt><dd>" \
+ "<input type=\"radio\" name=\"language\" value=\"no-lang\" checked>none</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"en\">English</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"de\">German</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"fr\">French</input>" \
+ "<input type=\"radio\" name=\"language\" value=\"es\">Spanish</input></dd>\n" \
+ "<dt>File:</dt><dd>" \
+ "<input type=\"file\" name=\"upload\"/></dd></dl>" \
+ "<input type=\"submit\" value=\"Send!\"/>\n" \
+ "</form>\n" \
+ "<h1>Download</h1>\n" \
+ "<ol>\n"
/**
* Footer of index page.
@@ -115,16 +131,15 @@
* NULL-terminated array of supported upload categories. Should match HTML
* in the form.
*/
-static const char * const categories[] =
- {
- "books",
- "images",
- "music",
- "software",
- "videos",
- "other",
- NULL,
- };
+static const char *const categories[] = {
+ "books",
+ "images",
+ "music",
+ "software",
+ "videos",
+ "other",
+ NULL,
+};
/**
@@ -148,15 +163,14 @@
* NULL-terminated array of supported upload categories. Should match HTML
* in the form.
*/
-static const struct Language languages[] =
- {
- { "no-lang", "No language specified" },
- { "en", "English" },
- { "de", "German" },
- { "fr", "French" },
- { "es", "Spanish" },
- { NULL, NULL },
- };
+static const struct Language languages[] = {
+ { "no-lang", "No language specified" },
+ { "en", "English" },
+ { "de", "German" },
+ { "fr", "French" },
+ { "es", "Spanish" },
+ { NULL, NULL },
+};
/**
@@ -184,14 +198,16 @@
*/
static pthread_mutex_t mutex;
+#ifdef MHD_HAVE_LIBMAGIC
/**
* Global handle to MAGIC data.
*/
static magic_t magic;
+#endif /* MHD_HAVE_LIBMAGIC */
/**
- * Mark the given response as HTML for the brower.
+ * Mark the given response as HTML for the browser.
*
* @param response response to mark
*/
@@ -199,8 +215,8 @@
mark_as_html (struct MHD_Response *response)
{
(void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html");
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html");
}
@@ -251,9 +267,9 @@
* @param dirname name of the directory to list
* @return MHD_YES on success, MHD_NO on error
*/
-static int
+static enum MHD_Result
list_directory (struct ResponseDataContext *rdc,
- const char *dirname)
+ const char *dirname)
{
char fullname[PATH_MAX];
struct stat sbuf;
@@ -263,35 +279,35 @@
if (NULL == (dir = opendir (dirname)))
return MHD_NO;
while (NULL != (de = readdir (dir)))
- {
- if ('.' == de->d_name[0])
- continue;
- if (sizeof (fullname) <= (size_t)
- snprintf (fullname, sizeof (fullname),
- "%s/%s",
- dirname, de->d_name))
- continue; /* ugh, file too long? how can this be!? */
- if (0 != stat (fullname, &sbuf))
- continue; /* ugh, failed to 'stat' */
- if (! S_ISREG (sbuf.st_mode))
- continue; /* not a regular file, skip */
- if (rdc->off + 1024 > rdc->buf_len)
- {
- void *r;
-
- if ( (2 * rdc->buf_len + 1024) < rdc->buf_len)
- break; /* more than SIZE_T _index_ size? Too big for us */
- rdc->buf_len = 2 * rdc->buf_len + 1024;
- if (NULL == (r = realloc (rdc->buf, rdc->buf_len)))
- break; /* out of memory */
- rdc->buf = r;
- }
- rdc->off += snprintf (&rdc->buf[rdc->off],
- rdc->buf_len - rdc->off,
- "<li><a href=\"/%s\">%s</a></li>\n",
- fullname,
- de->d_name);
- }
+ {
+ if ('.' == de->d_name[0])
+ continue;
+ if (sizeof (fullname) <= (size_t)
+ snprintf (fullname, sizeof (fullname),
+ "%s/%s",
+ dirname, de->d_name))
+ continue; /* ugh, file too long? how can this be!? */
+ if (0 != stat (fullname, &sbuf))
+ continue; /* ugh, failed to 'stat' */
+ if (! S_ISREG (sbuf.st_mode))
+ continue; /* not a regular file, skip */
+ if (rdc->off + 1024 > rdc->buf_len)
+ {
+ void *r;
+
+ if ( (2 * rdc->buf_len + 1024) < rdc->buf_len)
+ break; /* more than SIZE_T _index_ size? Too big for us */
+ rdc->buf_len = 2 * rdc->buf_len + 1024;
+ if (NULL == (r = realloc (rdc->buf, rdc->buf_len)))
+ break; /* out of memory */
+ rdc->buf = r;
+ }
+ rdc->off += snprintf (&rdc->buf[rdc->off],
+ rdc->buf_len - rdc->off,
+ "<li><a href=\"/%s\">%s</a></li>\n",
+ fullname,
+ de->d_name);
+ }
(void) closedir (dir);
return MHD_YES;
}
@@ -315,65 +331,66 @@
rdc.buf_len = initial_allocation;
if (NULL == (rdc.buf = malloc (rdc.buf_len)))
- {
- update_cached_response (NULL);
- return;
- }
+ {
+ update_cached_response (NULL);
+ return;
+ }
rdc.off = snprintf (rdc.buf, rdc.buf_len,
- "%s",
- INDEX_PAGE_HEADER);
- for (language_idx = 0; NULL != languages[language_idx].dirname; language_idx++)
- {
- language = &languages[language_idx];
+ "%s",
+ INDEX_PAGE_HEADER);
+ for (language_idx = 0; NULL != languages[language_idx].dirname;
+ language_idx++)
+ {
+ language = &languages[language_idx];
+
+ if (0 != stat (language->dirname, &sbuf))
+ continue; /* empty */
+ /* we ensured always +1k room, filenames are ~256 bytes,
+ so there is always still enough space for the header
+ without need for an additional reallocation check. */
+ rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
+ "<h2>%s</h2>\n",
+ language->longname);
+ for (category_idx = 0; NULL != categories[category_idx]; category_idx++)
+ {
+ category = categories[category_idx];
+ snprintf (dir_name, sizeof (dir_name),
+ "%s/%s",
+ language->dirname,
+ category);
+ if (0 != stat (dir_name, &sbuf))
+ continue; /* empty */
- if (0 != stat (language->dirname, &sbuf))
- continue; /* empty */
/* we ensured always +1k room, filenames are ~256 bytes,
- so there is always still enough space for the header
- without need for an additional reallocation check. */
+ so there is always still enough space for the header
+ without need for an additional reallocation check. */
rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "<h2>%s</h2>\n",
- language->longname);
- for (category_idx = 0; NULL != categories[category_idx]; category_idx++)
- {
- category = categories[category_idx];
- snprintf (dir_name, sizeof (dir_name),
- "%s/%s",
- language->dirname,
- category);
- if (0 != stat (dir_name, &sbuf))
- continue; /* empty */
-
- /* we ensured always +1k room, filenames are ~256 bytes,
- so there is always still enough space for the header
- without need for an additional reallocation check. */
- rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "<h3>%s</h3>\n",
- category);
-
- if (MHD_NO == list_directory (&rdc, dir_name))
- {
- free (rdc.buf);
- update_cached_response (NULL);
- return;
- }
- }
+ "<h3>%s</h3>\n",
+ category);
+
+ if (MHD_NO == list_directory (&rdc, dir_name))
+ {
+ free (rdc.buf);
+ update_cached_response (NULL);
+ return;
+ }
}
+ }
/* we ensured always +1k room, filenames are ~256 bytes,
so there is always still enough space for the footer
without need for a final reallocation check. */
rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
- "%s",
- INDEX_PAGE_FOOTER);
+ "%s",
+ INDEX_PAGE_FOOTER);
initial_allocation = rdc.buf_len; /* remember for next time */
response = MHD_create_response_from_buffer (rdc.off,
- rdc.buf,
- MHD_RESPMEM_MUST_FREE);
+ rdc.buf,
+ MHD_RESPMEM_MUST_FREE);
mark_as_html (response);
#if FORCE_CLOSE
(void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONNECTION,
- "close");
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
#endif
update_cached_response (response);
}
@@ -428,12 +445,12 @@
* @param ret string to update, NULL or 0-terminated
* @param data data to append
* @param size number of bytes in 'data'
- * @return MHD_NO on allocation failure, MHD_YES on success
+ * @return #MHD_NO on allocation failure, #MHD_YES on success
*/
-static int
+static enum MHD_Result
do_append (char **ret,
- const char *data,
- size_t size)
+ const char *data,
+ size_t size)
{
char *buf;
size_t old_len;
@@ -442,13 +459,18 @@
old_len = 0;
else
old_len = strlen (*ret);
- buf = malloc (old_len + size + 1);
- if (NULL == buf)
+ if (NULL == (buf = malloc (old_len + size + 1)))
return MHD_NO;
- memcpy (buf, *ret, old_len);
if (NULL != *ret)
+ {
+ memcpy (buf,
+ *ret,
+ old_len);
free (*ret);
- memcpy (&buf[old_len], data, size);
+ }
+ memcpy (&buf[old_len],
+ data,
+ size);
buf[old_len + size] = '\0';
*ret = buf;
return MHD_YES;
@@ -471,120 +493,124 @@
* specified offset
* @param off offset of data in the overall value
* @param size number of bytes in data available
- * @return MHD_YES to continue iterating,
- * MHD_NO to abort the iteration
+ * @return #MHD_YES to continue iterating,
+ * #MHD_NO to abort the iteration
*/
-static int
+static enum MHD_Result
process_upload_data (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *filename,
- const char *content_type,
- const char *transfer_encoding,
- const char *data,
- uint64_t off,
- size_t size)
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
{
struct UploadContext *uc = cls;
int i;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
+ (void) off; /* Unused. Silent compiler warning. */
if (0 == strcmp (key, "category"))
return do_append (&uc->category, data, size);
if (0 == strcmp (key, "language"))
return do_append (&uc->language, data, size);
if (0 != strcmp (key, "upload"))
- {
- fprintf (stderr,
- "Ignoring unexpected form value `%s'\n",
- key);
- return MHD_YES; /* ignore */
- }
+ {
+ fprintf (stderr,
+ "Ignoring unexpected form value `%s'\n",
+ key);
+ return MHD_YES; /* ignore */
+ }
if (NULL == filename)
- {
- fprintf (stderr, "No filename, aborting upload\n");
- return MHD_NO; /* no filename, error */
- }
+ {
+ fprintf (stderr, "No filename, aborting upload.\n");
+ return MHD_NO; /* no filename, error */
+ }
if ( (NULL == uc->category) ||
(NULL == uc->language) )
+ {
+ fprintf (stderr,
+ "Missing form data for upload `%s'\n",
+ filename);
+ uc->response = request_refused_response;
+ return MHD_NO;
+ }
+ if (-1 == uc->fd)
+ {
+ char fn[PATH_MAX];
+
+ if ( (NULL != strstr (filename, "..")) ||
+ (NULL != strchr (filename, '/')) ||
+ (NULL != strchr (filename, '\\')) )
{
- fprintf (stderr,
- "Missing form data for upload `%s'\n",
- filename);
uc->response = request_refused_response;
return MHD_NO;
}
- if (-1 == uc->fd)
- {
- char fn[PATH_MAX];
-
- if ( (NULL != strstr (filename, "..")) ||
- (NULL != strchr (filename, '/')) ||
- (NULL != strchr (filename, '\\')) )
- {
- uc->response = request_refused_response;
- return MHD_NO;
- }
- /* create directories -- if they don't exist already */
+ /* create directories -- if they don't exist already */
#ifdef WINDOWS
- (void) mkdir (uc->language);
+ (void) mkdir (uc->language);
#else
- (void) mkdir (uc->language, S_IRWXU);
+ (void) mkdir (uc->language, S_IRWXU);
#endif
- snprintf (fn, sizeof (fn),
- "%s/%s",
- uc->language,
- uc->category);
+ snprintf (fn, sizeof (fn),
+ "%s/%s",
+ uc->language,
+ uc->category);
#ifdef WINDOWS
- (void) mkdir (fn);
+ (void) mkdir (fn);
#else
- (void) mkdir (fn, S_IRWXU);
+ (void) mkdir (fn, S_IRWXU);
#endif
- /* open file */
- snprintf (fn, sizeof (fn),
- "%s/%s/%s",
- uc->language,
- uc->category,
- filename);
- for (i=strlen (fn)-1;i>=0;i--)
- if (! isprint ((int) fn[i]))
- fn[i] = '_';
- uc->fd = open (fn,
- O_CREAT | O_EXCL
+ /* open file */
+ snprintf (fn, sizeof (fn),
+ "%s/%s/%s",
+ uc->language,
+ uc->category,
+ filename);
+ for (i = strlen (fn) - 1; i>=0; i--)
+ if (! isprint ((unsigned char) fn[i]))
+ fn[i] = '_';
+ uc->fd = open (fn,
+ O_CREAT | O_EXCL
#if O_LARGEFILE
- | O_LARGEFILE
+ | O_LARGEFILE
#endif
- | O_WRONLY,
- S_IRUSR | S_IWUSR);
- if (-1 == uc->fd)
- {
- fprintf (stderr,
- "Error opening file `%s' for upload: %s\n",
- fn,
- strerror (errno));
- uc->response = request_refused_response;
- return MHD_NO;
- }
- uc->filename = strdup (fn);
+ | O_WRONLY,
+ S_IRUSR | S_IWUSR);
+ if (-1 == uc->fd)
+ {
+ fprintf (stderr,
+ "Error opening file `%s' for upload: %s\n",
+ fn,
+ strerror (errno));
+ uc->response = request_refused_response;
+ return MHD_NO;
}
+ uc->filename = strdup (fn);
+ }
if ( (0 != size) &&
(size != (size_t) write (uc->fd, data, size)) )
+ {
+ /* write failed; likely: disk full */
+ fprintf (stderr,
+ "Error writing to file `%s': %s\n",
+ uc->filename,
+ strerror (errno));
+ uc->response = internal_error_response;
+ close (uc->fd);
+ uc->fd = -1;
+ if (NULL != uc->filename)
{
- /* write failed; likely: disk full */
- fprintf (stderr,
- "Error writing to file `%s': %s\n",
- uc->filename,
- strerror (errno));
- uc->response = internal_error_response;
- close (uc->fd);
- uc->fd = -1;
- if (NULL != uc->filename)
- {
- unlink (uc->filename);
- free (uc->filename);
- uc->filename = NULL;
- }
- return MHD_NO;
+ unlink (uc->filename);
+ free (uc->filename);
+ uc->filename = NULL;
}
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -602,29 +628,32 @@
*/
static void
response_completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct UploadContext *uc = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == uc)
return; /* this request wasn't an upload request */
if (NULL != uc->pp)
- {
- MHD_destroy_post_processor (uc->pp);
- uc->pp = NULL;
- }
+ {
+ MHD_destroy_post_processor (uc->pp);
+ uc->pp = NULL;
+ }
if (-1 != uc->fd)
{
(void) close (uc->fd);
if (NULL != uc->filename)
- {
- fprintf (stderr,
- "Upload of file `%s' failed (incomplete or aborted), removing file.\n",
- uc->filename);
- (void) unlink (uc->filename);
- }
+ {
+ fprintf (stderr,
+ "Upload of file `%s' failed (incomplete or aborted), removing file.\n",
+ uc->filename);
+ (void) unlink (uc->filename);
+ }
}
if (NULL != uc->filename)
free (uc->filename);
@@ -638,20 +667,20 @@
* @param connection connection to return the directory for
* @return MHD_YES on success, MHD_NO on error
*/
-static int
+static enum MHD_Result
return_directory_response (struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
(void) pthread_mutex_lock (&mutex);
if (NULL == cached_directory_response)
ret = MHD_queue_response (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- internal_error_response);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ internal_error_response);
else
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- cached_directory_response);
+ MHD_HTTP_OK,
+ cached_directory_response);
(void) pthread_mutex_unlock (&mutex);
return ret;
}
@@ -670,127 +699,133 @@
* @param ptr our context
* @return #MHD_YES on success, #MHD_NO to drop connection
*/
-static int
+static enum MHD_Result
generate_page (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size, void **ptr)
{
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int fd;
struct stat buf;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
if (0 != strcmp (url, "/"))
+ {
+ /* should be file download */
+#ifdef MHD_HAVE_LIBMAGIC
+ char file_data[MAGIC_HEADER_SIZE];
+ ssize_t got;
+#endif /* MHD_HAVE_LIBMAGIC */
+ const char *mime;
+
+ if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+ return MHD_NO; /* unexpected method (we're not polite...) */
+ fd = -1;
+ if ( (NULL == strstr (&url[1], "..")) &&
+ ('/' != url[1]) )
+ {
+ fd = open (&url[1], O_RDONLY);
+ if ( (-1 != fd) &&
+ ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) ) )
+ {
+ (void) close (fd);
+ fd = -1;
+ }
+ }
+ if (-1 == fd)
+ return MHD_queue_response (connection,
+ MHD_HTTP_NOT_FOUND,
+ file_not_found_response);
+#ifdef MHD_HAVE_LIBMAGIC
+ /* read beginning of the file to determine mime type */
+ got = read (fd, file_data, sizeof (file_data));
+ (void) lseek (fd, 0, SEEK_SET);
+ if (-1 != got)
+ mime = magic_buffer (magic, file_data, got);
+ else
+#endif /* MHD_HAVE_LIBMAGIC */
+ mime = NULL;
+
+ if (NULL == (response = MHD_create_response_from_fd (buf.st_size,
+ fd)))
{
- /* should be file download */
- char file_data[MAGIC_HEADER_SIZE];
- ssize_t got;
- const char *mime;
-
- if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
- return MHD_NO; /* unexpected method (we're not polite...) */
- fd = -1;
- if ( (NULL == strstr (&url[1], "..")) &&
- ('/' != url[1]) )
- {
- fd = open (&url[1], O_RDONLY);
- if ( (-1 != fd) &&
- ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) ) )
- {
- (void) close (fd);
- fd = -1;
- }
- }
- if (-1 == fd)
- return MHD_queue_response (connection,
- MHD_HTTP_NOT_FOUND,
- file_not_found_response);
- /* read beginning of the file to determine mime type */
- got = read (fd, file_data, sizeof (file_data));
- if (-1 != got)
- mime = magic_buffer (magic, file_data, got);
- else
- mime = NULL;
- (void) lseek (fd, 0, SEEK_SET);
-
- if (NULL == (response = MHD_create_response_from_fd (buf.st_size,
- fd)))
- {
- /* internal error (i.e. out of memory) */
- (void) close (fd);
- return MHD_NO;
- }
-
- /* add mime type if we had one */
- if (NULL != mime)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- mime);
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- return ret;
+ /* internal error (i.e. out of memory) */
+ (void) close (fd);
+ return MHD_NO;
}
+ /* add mime type if we had one */
+ if (NULL != mime)
+ (void) MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ mime);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+ }
+
if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
- {
- /* upload! */
- struct UploadContext *uc = *ptr;
+ {
+ /* upload! */
+ struct UploadContext *uc = *ptr;
- if (NULL == uc)
- {
- if (NULL == (uc = malloc (sizeof (struct UploadContext))))
- return MHD_NO; /* out of memory, close connection */
- memset (uc, 0, sizeof (struct UploadContext));
- uc->fd = -1;
- uc->connection = connection;
- uc->pp = MHD_create_post_processor (connection,
- 64 * 1024 /* buffer size */,
- &process_upload_data, uc);
- if (NULL == uc->pp)
- {
- /* out of memory, close connection */
- free (uc);
- return MHD_NO;
- }
- *ptr = uc;
- return MHD_YES;
- }
- if (0 != *upload_data_size)
- {
- if (NULL == uc->response)
- (void) MHD_post_process (uc->pp,
- upload_data,
- *upload_data_size);
- *upload_data_size = 0;
- return MHD_YES;
- }
- /* end of upload, finish it! */
- MHD_destroy_post_processor (uc->pp);
- uc->pp = NULL;
- if (-1 != uc->fd)
- {
- close (uc->fd);
- uc->fd = -1;
- }
- if (NULL != uc->response)
- {
- return MHD_queue_response (connection,
- MHD_HTTP_FORBIDDEN,
- uc->response);
- }
- else
- {
- update_directory ();
- return return_directory_response (connection);
- }
+ if (NULL == uc)
+ {
+ if (NULL == (uc = malloc (sizeof (struct UploadContext))))
+ return MHD_NO; /* out of memory, close connection */
+ memset (uc, 0, sizeof (struct UploadContext));
+ uc->fd = -1;
+ uc->connection = connection;
+ uc->pp = MHD_create_post_processor (connection,
+ 64 * 1024 /* buffer size */,
+ &process_upload_data, uc);
+ if (NULL == uc->pp)
+ {
+ /* out of memory, close connection */
+ free (uc);
+ return MHD_NO;
+ }
+ *ptr = uc;
+ return MHD_YES;
+ }
+ if (0 != *upload_data_size)
+ {
+ if (NULL == uc->response)
+ (void) MHD_post_process (uc->pp,
+ upload_data,
+ *upload_data_size);
+ *upload_data_size = 0;
+ return MHD_YES;
+ }
+ /* end of upload, finish it! */
+ MHD_destroy_post_processor (uc->pp);
+ uc->pp = NULL;
+ if (-1 != uc->fd)
+ {
+ close (uc->fd);
+ uc->fd = -1;
+ }
+ if (NULL != uc->response)
+ {
+ return MHD_queue_response (connection,
+ MHD_HTTP_FORBIDDEN,
+ uc->response);
+ }
+ else
+ {
+ update_directory ();
+ return return_directory_response (connection);
}
+ }
if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
{
return return_directory_response (connection);
@@ -798,11 +833,12 @@
/* unexpected request, refuse */
return MHD_queue_response (connection,
- MHD_HTTP_FORBIDDEN,
- request_refused_response);
+ MHD_HTTP_FORBIDDEN,
+ request_refused_response);
}
+#ifndef MINGW
/**
* Function called if we get a SIGPIPE. Does nothing.
*
@@ -811,6 +847,7 @@
static void
catcher (int sig)
{
+ (void) sig; /* Unused. Silent compiler warning. */
/* do nothing */
}
@@ -818,9 +855,8 @@
/**
* setup handlers to ignore SIGPIPE.
*/
-#ifndef MINGW
static void
-ignore_sigpipe ()
+ignore_sigpipe (void)
{
struct sigaction oldsig;
struct sigaction sig;
@@ -836,57 +872,74 @@
fprintf (stderr,
"Failed to install SIGPIPE handler: %s\n", strerror (errno));
}
+
+
#endif
/* test server key */
-const char srv_signed_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEowIBAAKCAQEAvfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW\n"
- "+K03KwEku55QvnUndwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8IL\n"
- "q4sw32vo0fbMu5BZF49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ0\n"
- "20Q5EAAEseD1YtWCIpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6\n"
- "QYGGh1QmHRPAy3CBII6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6x\n"
- "yoOl204xuekZOaG9RUPId74Rtmwfi1TLbBzo2wIDAQABAoIBADu09WSICNq5cMe4\n"
- "+NKCLlgAT1NiQpLls1gKRbDhKiHU9j8QWNvWWkJWrCya4QdUfLCfeddCMeiQmv3K\n"
- "lJMvDs+5OjJSHFoOsGiuW2Ias7IjnIojaJalfBml6frhJ84G27IXmdz6gzOiTIer\n"
- "DjeAgcwBaKH5WwIay2TxIaScl7AwHBauQkrLcyb4hTmZuQh6ArVIN6+pzoVuORXM\n"
- "bpeNWl2l/HSN3VtUN6aCAKbN/X3o0GavCCMn5Fa85uJFsab4ss/uP+2PusU71+zP\n"
- "sBm6p/2IbGvF5k3VPDA7X5YX61sukRjRBihY8xSnNYx1UcoOsX6AiPnbhifD8+xQ\n"
- "Tlf8oJUCgYEA0BTfzqNpr9Wxw5/QXaSdw7S/0eP5a0C/nwURvmfSzuTD4equzbEN\n"
- "d+dI/s2JMxrdj/I4uoAfUXRGaabevQIjFzC9uyE3LaOyR2zhuvAzX+vVcs6bSXeU\n"
- "pKpCAcN+3Z3evMaX2f+z/nfSUAl2i4J2R+/LQAWJW4KwRky/m+cxpfUCgYEA6bN1\n"
- "b73bMgM8wpNt6+fcmS+5n0iZihygQ2U2DEud8nZJL4Nrm1dwTnfZfJBnkGj6+0Q0\n"
- "cOwj2KS0/wcEdJBP0jucU4v60VMhp75AQeHqidIde0bTViSRo3HWKXHBIFGYoU3T\n"
- "LyPyKndbqsOObnsFXHn56Nwhr2HLf6nw4taGQY8CgYBoSW36FLCNbd6QGvLFXBGt\n"
- "2lMhEM8az/K58kJ4WXSwOLtr6MD/WjNT2tkcy0puEJLm6BFCd6A6pLn9jaKou/92\n"
- "SfltZjJPb3GUlp9zn5tAAeSSi7YMViBrfuFiHObij5LorefBXISLjuYbMwL03MgH\n"
- "Ocl2JtA2ywMp2KFXs8GQWQKBgFyIVv5ogQrbZ0pvj31xr9HjqK6d01VxIi+tOmpB\n"
- "4ocnOLEcaxX12BzprW55ytfOCVpF1jHD/imAhb3YrHXu0fwe6DXYXfZV4SSG2vB7\n"
- "IB9z14KBN5qLHjNGFpMQXHSMek+b/ftTU0ZnPh9uEM5D3YqRLVd7GcdUhHvG8P8Q\n"
- "C9aXAoGBAJtID6h8wOGMP0XYX5YYnhlC7dOLfk8UYrzlp3xhqVkzKthTQTj6wx9R\n"
- "GtC4k7U1ki8oJsfcIlBNXd768fqDVWjYju5rzShMpo8OCTS6ipAblKjCxPPVhIpv\n"
- "tWPlbSn1qj6wylstJ5/3Z+ZW5H4wIKp5jmLiioDhcP0L/Ex3Zx8O\n"
- "-----END RSA PRIVATE KEY-----\n";
+const char srv_signed_key_pem[] =
+ "-----BEGIN PRIVATE KEY-----\n\
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrm8uH8V0P2Xbl\n\
+HCMq6PTIphDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZ\n\
+Vyg4ksOA7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd\n\
+6mi978n//bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5yg\n\
+CR99TDDHZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/Lni\n\
+CGO9uXGOgZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF\n\
+1N8GZZC7AgMBAAECggEAc0F/wR3qUurLX7U2KWuse9aNHFb84mBfCAw3hj7ddFEl\n\
+wto7EB50MA0KY4OI8u6fQH4E8zINoAciDzLqYJSxmbZhC1N5YX/Yc3qtZdB2b5tj\n\
+anbsSQqVo8YVPVDU4bCsG9vhArdd4JdCnD0DfA3ArZ3JAPwHsB4Ks1icLSOIGz0/\n\
+JvOZEryJBdwM6SKbzLMqVOGmYDiY6s7UpJ0rg3cOPqhdg5xv8XZATqXISU0mLBcq\n\
+RiS7lHZERASYON2rpznhBiCtikOcr/duQhvZ1uDSGfDzDJil+1hdS3RouS9WZCIe\n\
+p3CtvZhPLmv6kFg9YE+AovDwOOwNr0no3H9oJA2FgQKBgQDSWrE/MRMRpFJFBxxC\n\
+YckC2v8Y+7sVSMbFNq/0j2eRTql+8AeZBbAoGU4QHUcylCBkv33zDYRY52xNo32E\n\
+8mmH2O/pIcYy0LafrVZHdulf+fxybncObidxmmjR9C8aLzwRuIMtABz4simaQcBD\n\
+RhZJ1YCqVkfMr/PlbLzvC8V+FwKBgQDQ2MF/Yz/p7QEDHpfKdtx7+yK6i8IM+V8l\n\
+d2OuscNkQQywCVqE2vyRZJbjU9y+Om7alNKFPhhBzavdOxNWXGXmlBIlvo3v6M++\n\
+fTixza77LxHvbghH0ykplSwGh30vpHtvoxsRS5nRFxmsVK9jNYYT/Aes+J6MXlq7\n\
+PYAiZVQs/QKBgFKYY8JhPZCOyfLqsNDr3matoL6pkTLxSYMETyCi8lKe5XS/QOx3\n\
+zExia0FujZcxjGqiugymgRH7hI4TpOR/3qoFp2YN6enoA908zYTwDwCtgs9Xyo2y\n\
++O/lZkUSMTCB3X9DyNXxlm6cXjOAn8KKkZPaLlQz3qtjZ0vtX14pbBlvAoGBAKw0\n\
+vsCifvYNZhNDa5gXkFBu0MEPMm/uQ+Up37kRfPKyrJqO6+O2iiH81moWIWN93SBB\n\
+LKGPhQLlazxdVOGWCLQrDhevW2wiBQKmUFRULF+T/W72xL8sv7k49ndfyvq43ss7\n\
+q7sEIo4FRTcTERd179uUqmOXEWze9GOGH5y8/r6lAoGAG2YyqRWF+yxKlgR71b1Q\n\
+Zxv53WgXOUwemGRbXxE4g3gHpW5k9zWh4QTkbd0lDD+SQ0DBwZl/x/FWj43jUS+i\n\
+a5UojDUx8nYgjiAO7kppMlX3ZaJD1DkwEz+4HW9oPmOFt8smvuTVt0mm6tpmQdRA\n\
+yLwgQzGDGVJB6ETVJS7cwWs=\n\
+-----END PRIVATE KEY-----";
/* test server CA signed certificates */
-const char srv_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
- "MIIDGzCCAgWgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
- "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
- "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
- "vfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW+K03KwEku55QvnUn\n"
- "dwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8ILq4sw32vo0fbMu5BZ\n"
- "F49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ020Q5EAAEseD1YtWC\n"
- "IpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6QYGGh1QmHRPAy3CB\n"
- "II6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6xyoOl204xuekZOaG9\n"
- "RUPId74Rtmwfi1TLbBzo2wIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
- "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFOFi4ilKOP1d\n"
- "XHlWCMwmVKr7mgy8MB8GA1UdIwQYMBaAFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsG\n"
- "CSqGSIb3DQEBBQOCAQEAHVWPxazupbOkG7Did+dY9z2z6RjTzYvurTtEKQgzM2Vz\n"
- "GQBA+3pZ3c5mS97fPIs9hZXfnQeelMeZ2XP1a+9vp35bJjZBBhVH+pqxjCgiUflg\n"
- "A3Zqy0XwwVCgQLE2HyaU3DLUD/aeIFK5gJaOSdNTXZLv43K8kl4cqDbMeRpVTbkt\n"
- "YmG4AyEOYRNKGTqMEJXJoxD5E3rBUNrVI/XyTjYrulxbNPcMWEHKNeeqWpKDYTFo\n"
- "Bb01PCthGXiq/4A2RLAFosadzRa8SBpoSjPPfZ0b2w4MJpReHqKbR5+T2t6hzml6\n"
- "4ToyOKPDmamiTuN5KzLN3cw7DQlvWMvqSOChPLnA3Q==\n"
- "-----END CERTIFICATE-----\n";
+const char srv_signed_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIFaTCCA1GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MjFaGA8yMTIxMDMxMzE3\n\
+MzYyMVowgYcxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMRQwEgYDVQQDDAt0\n\
+ZXN0LXNlcnZlcjEjMCEGA1UdEQwaRE5TOmxvY2FsaG9zdCxJUDoxMjcuMC4wLjEw\n\
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrm8uH8V0P2XblHCMq6PTI\n\
+phDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZVyg4ksOA\n\
+7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd6mi978n/\n\
+/bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5ygCR99TDDH\n\
+ZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/LniCGO9uXGO\n\
+gZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF1N8GZZC7\n\
+AgMBAAGjgeEwgd4wCwYDVR0PBAQDAgWgMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n\
+BAwwCgYIKwYBBQUHAwEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAA\n\
+AAAAAAAAAAAAAAABMB0GA1UdDgQWBBRifkHd2xWI51NhnH8sL66K8EedpjAoBglg\n\
+hkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBkIHNlcnZlcjARBglghkgBhvhC\n\
+AQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOFNd0arI3/QB3W6SwwDQYJKoZI\n\
+hvcNAQELBQADggIBAJoIyNrnwQ+7WcJDaBjjuwSH0ORuK+E3zRI3+nDde08gyfeG\n\
+K4QozT2L574WzadTVLSiin9lRShYlp0nr60pmUb9+SKE0O7Cx+rYV0Rfu0KLYsYh\n\
+sAkb9J9t1fdIt54fXNcUtvfGPyM2lEI0KxMCGNV2wXDnwzdSNIU6Nk457MntfZdi\n\
+r1ISnS6fLd0BIKIGxfCFb10CexhNOSaExgpp1bxZovdYaQWggL0u8eC8j00sJ1C5\n\
+Qo4gQ1TQsead6zMs6m19TPLlV7hS+hfXj7yeJ/TTUj69bCjTIMp6HCFnfQbD84BI\n\
+HZDKk4Tob9vBRCKbY58kNXHyQ4nxvSCBlKI03VJjvzpsKTI/vW9JBivtnYtMbMl9\n\
+ouZal/IVsNqRCeiMTLky62qrFhZr2DHgPG5VcOGQ4y0X4vOgM9n/MMOGWcNBByLX\n\
+b5ZaYr7DPCcz9dYZgEbwXj8wnuAzM1sJ2igwTmO/vQsn1G2Q/h/JB471CD1avuuI\n\
+awKRqhU2KhYVrwo7ahJkPV9Lm6eoavq2Tu+e1o4qAFhPLMy/6F+bZmK6GfHMvP+L\n\
+v+GOQdUJ/vMMus/HB5N3cUZsu9rGnCCVgPW7pkHrp5bRtuVzBT78ISsxkGnOhfT7\n\
+6Kp7ApvfEX6/Y/vbDFBC4kyAvEIZ+F8AUkbvZ0+k8j5xlarNd6TQ3slEGi6O\n\
+-----END CERTIFICATE-----";
/**
@@ -907,48 +960,63 @@
if ( (argc != 2) ||
(1 != sscanf (argv[1], "%u", &port)) ||
(UINT16_MAX < port) )
- {
- fprintf (stderr,
- "%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ fprintf (stderr,
+ "%s PORT\n", argv[0]);
+ return 1;
+ }
#ifndef MINGW
ignore_sigpipe ();
#endif
+#ifdef MHD_HAVE_LIBMAGIC
magic = magic_open (MAGIC_MIME_TYPE);
(void) magic_load (magic, NULL);
+#endif /* MHD_HAVE_LIBMAGIC */
(void) pthread_mutex_init (&mutex, NULL);
- file_not_found_response = MHD_create_response_from_buffer (strlen (FILE_NOT_FOUND_PAGE),
- (void *) FILE_NOT_FOUND_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ file_not_found_response = MHD_create_response_from_buffer (strlen (
+ FILE_NOT_FOUND_PAGE),
+ (void *)
+ FILE_NOT_FOUND_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (file_not_found_response);
- request_refused_response = MHD_create_response_from_buffer (strlen (REQUEST_REFUSED_PAGE),
- (void *) REQUEST_REFUSED_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ request_refused_response = MHD_create_response_from_buffer (strlen (
+ REQUEST_REFUSED_PAGE),
+ (void *)
+ REQUEST_REFUSED_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (request_refused_response);
- internal_error_response = MHD_create_response_from_buffer (strlen (INTERNAL_ERROR_PAGE),
- (void *) INTERNAL_ERROR_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ internal_error_response = MHD_create_response_from_buffer (strlen (
+ INTERNAL_ERROR_PAGE),
+ (void *)
+ INTERNAL_ERROR_PAGE,
+ MHD_RESPMEM_PERSISTENT);
mark_as_html (internal_error_response);
update_directory ();
- d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_TLS,
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG | MHD_USE_TLS,
port,
NULL, NULL,
- &generate_page, NULL,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024),
+ &generate_page, NULL,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256
+ * 1024),
#if PRODUCTION
- MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
+ MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
#endif
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) (120 /* seconds */),
- MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
- MHD_OPTION_NOTIFY_COMPLETED, &response_completed_callback, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned
+ int) (120 /* seconds */),
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned
+ int) NUMBER_OF_THREADS,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ &response_completed_callback, NULL,
+ /* Optionally, the gnutls_load_file() can be used to
+ load the key and the certificate from file. */
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
- MHD_OPTION_END);
+ MHD_OPTION_END);
if (NULL == d)
return 1;
- fprintf (stderr, "HTTP server running. Press ENTER to stop the server\n");
+ fprintf (stderr, "HTTP server running. Press ENTER to stop the server.\n");
(void) getc (stdin);
MHD_stop_daemon (d);
MHD_destroy_response (file_not_found_response);
@@ -956,8 +1024,11 @@
MHD_destroy_response (internal_error_response);
update_cached_response (NULL);
(void) pthread_mutex_destroy (&mutex);
+#ifdef MHD_HAVE_LIBMAGIC
magic_close (magic);
+#endif /* MHD_HAVE_LIBMAGIC */
return 0;
}
+
/* end of demo_https.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/digest_auth_example.c
^
|
@@ -26,13 +26,15 @@
#include <microhttpd.h>
#include <stdlib.h>
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
-#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+#define DENIED \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
#define MY_OPAQUE_STR "11733b200778ce33060f31c9af70a870ba96ddd4"
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -44,48 +46,58 @@
char *username;
const char *password = "testpass";
const char *realm = "test@example.com";
- int ret;
-
- username = MHD_digest_auth_get_username(connection);
- if (username == NULL)
- {
- response = MHD_create_response_from_buffer(strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE_STR,
- response,
- MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- ret = MHD_digest_auth_check(connection, realm,
- username,
- password,
- 300);
- free(username);
- if ( (ret == MHD_INVALID_NONCE) ||
- (ret == MHD_NO) )
- {
- response = MHD_create_response_from_buffer(strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- return MHD_NO;
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE_STR,
- response,
- (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
+ int res;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) method; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) ptr; /* Unused. Silent compiler warning. */
+
+ username = MHD_digest_auth_get_username (connection);
+ if (NULL == username)
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_auth_fail_response (connection, realm,
+ MY_OPAQUE_STR,
+ response,
+ MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ res = MHD_digest_auth_check (connection, realm,
+ username,
+ password,
+ 300);
+ MHD_free (username);
+ if ( (res == MHD_INVALID_NONCE) ||
+ (res == MHD_NO) )
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_auth_fail_response (connection, realm,
+ MY_OPAQUE_STR,
+ response,
+ (res == MHD_INVALID_NONCE) ? MHD_YES :
+ MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ response = MHD_create_response_from_buffer (strlen (PAGE), PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
return ret;
}
+
int
main (int argc, char *const *argv)
{
@@ -96,40 +108,41 @@
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- fd = open("/dev/urandom", O_RDONLY);
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ fd = open ("/dev/urandom", O_RDONLY);
if (-1 == fd)
- {
- fprintf (stderr, "Failed to open `%s': %s\n",
- "/dev/urandom",
- strerror (errno));
- return 1;
- }
+ {
+ fprintf (stderr, "Failed to open `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ return 1;
+ }
off = 0;
while (off < 8)
+ {
+ len = read (fd, rnd, 8);
+ if (len == -1)
{
- len = read(fd, rnd, 8);
- if (len == -1)
- {
- fprintf (stderr, "Failed to read `%s': %s\n",
- "/dev/urandom",
- strerror (errno));
- (void) close (fd);
- return 1;
- }
- off += len;
+ fprintf (stderr, "Failed to read `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ (void) close (fd);
+ return 1;
}
- (void) close(fd);
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ off += len;
+ }
+ (void) close (fd);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE,
- MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof(rnd), rnd,
- MHD_OPTION_NONCE_NC_SIZE, 300,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_END);
+ MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof(rnd), rnd,
+ MHD_OPTION_NONCE_NC_SIZE, 300,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
@@ -137,4 +150,5 @@
return 0;
}
+
/* end of digest_auth_example.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/dual_stack_example.c
^
|
@@ -25,9 +25,10 @@
#include "platform.h"
#include <microhttpd.h>
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -38,20 +39,24 @@
static int aptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (me),
- (void *) me,
- MHD_RESPMEM_PERSISTENT);
+ (void *) me,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -64,15 +69,16 @@
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_DUAL_STACK,
- atoi (argv[1]),
- NULL, NULL, &ahc_echo, PAGE,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_END);
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | MHD_USE_DUAL_STACK,
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, PAGE,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_END);
(void) getc (stdin);
MHD_stop_daemon (d);
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/fileserver_example.c
^
|
@@ -34,76 +34,81 @@
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
-#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
#ifndef S_ISREG
#define S_ISREG(x) (S_IFREG == (x & S_IFREG))
#endif /* S_ISREG */
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ size_t *upload_data_size, void **ptr)
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int fd;
struct stat buf;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
(0 != strcmp (method, MHD_HTTP_METHOD_HEAD)) )
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
- *ptr = NULL; /* reset when done */
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
/* WARNING: direct usage of url as filename is for example only!
* NEVER pass received data directly as parameter to file manipulation
* functions. Always check validity of data before using.
*/
- if (NULL != strstr(url, "../")) /* Very simplified check! */
- fd = -1; /* Do not allow usage of parent directories. */
+ if (NULL != strstr (url, "../")) /* Very simplified check! */
+ fd = -1; /* Do not allow usage of parent directories. */
else
fd = open (url + 1, O_RDONLY);
if (-1 != fd)
+ {
+ if ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) )
{
- if ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) )
- {
- /* not a regular file, refuse to serve */
- if (0 != close (fd))
- abort ();
- fd = -1;
- }
+ /* not a regular file, refuse to serve */
+ if (0 != close (fd))
+ abort ();
+ fd = -1;
}
+ }
if (-1 == fd)
- {
- response = MHD_create_response_from_buffer (strlen (PAGE),
- (void *) PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
- MHD_destroy_response (response);
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (PAGE),
+ (void *) PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
+ MHD_destroy_response (response);
+ }
else
+ {
+ response = MHD_create_response_from_fd64 (buf.st_size, fd);
+ if (NULL == response)
{
- response = MHD_create_response_from_fd64 (buf.st_size, fd);
- if (NULL == response)
- {
- if (0 != close (fd))
- abort ();
- return MHD_NO;
- }
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
+ if (0 != close (fd))
+ abort ();
+ return MHD_NO;
}
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ }
return ret;
}
@@ -114,11 +119,12 @@
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
if (d == NULL)
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/fileserver_example_dirs.c
^
|
@@ -28,7 +28,8 @@
#include <microhttpd.h>
#include <unistd.h>
-#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
static ssize_t
@@ -66,116 +67,121 @@
if (max < 512)
return 0;
+ (void) pos; /* 'pos' is ignored as function return next one single entry per call. */
do
- {
- e = readdir (dir);
- if (e == NULL)
- return MHD_CONTENT_READER_END_OF_STREAM;
+ {
+ e = readdir (dir);
+ if (e == NULL)
+ return MHD_CONTENT_READER_END_OF_STREAM;
} while (e->d_name[0] == '.');
return snprintf (buf, max,
- "<a href=\"/%s\">%s</a><br>",
- e->d_name,
- e->d_name);
+ "<a href=\"/%s\">%s</a><br>",
+ e->d_name,
+ e->d_name);
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ size_t *upload_data_size, void **ptr)
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
FILE *file;
int fd;
DIR *dir;
struct stat buf;
char emsg[1024];
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
file = fopen (&url[1], "rb");
if (NULL != file)
+ {
+ fd = fileno (file);
+ if (-1 == fd)
{
- fd = fileno (file);
- if (-1 == fd)
- {
- (void) fclose (file);
- return MHD_NO; /* internal error */
- }
- if ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) )
- {
- /* not a regular file, refuse to serve */
- fclose (file);
- file = NULL;
- }
+ (void) fclose (file);
+ return MHD_NO; /* internal error */
}
+ if ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) )
+ {
+ /* not a regular file, refuse to serve */
+ fclose (file);
+ file = NULL;
+ }
+ }
if (NULL == file)
- {
- dir = opendir (".");
- if (NULL == dir)
- {
- /* most likely cause: more concurrent requests than
- available file descriptors / 2 */
- snprintf (emsg,
- sizeof (emsg),
- "Failed to open directory `.': %s\n",
- strerror (errno));
- response = MHD_create_response_from_buffer (strlen (emsg),
- emsg,
- MHD_RESPMEM_MUST_COPY);
- if (NULL == response)
- return MHD_NO;
- ret = MHD_queue_response (connection,
- MHD_HTTP_SERVICE_UNAVAILABLE,
- response);
- MHD_destroy_response (response);
- }
- else
- {
- response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
- 32 * 1024,
- &dir_reader,
- dir,
- &dir_free_callback);
- if (NULL == response)
- {
- closedir (dir);
- return MHD_NO;
- }
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- }
+ {
+ dir = opendir (".");
+ if (NULL == dir)
+ {
+ /* most likely cause: more concurrent requests than
+ available file descriptors / 2 */
+ snprintf (emsg,
+ sizeof (emsg),
+ "Failed to open directory `.': %s\n",
+ strerror (errno));
+ response = MHD_create_response_from_buffer (strlen (emsg),
+ emsg,
+ MHD_RESPMEM_MUST_COPY);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_SERVICE_UNAVAILABLE,
+ response);
+ MHD_destroy_response (response);
}
- else
+ else
{
- response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
- &file_reader,
- file,
- &file_free_callback);
+ response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
+ 32 * 1024,
+ &dir_reader,
+ dir,
+ &dir_free_callback);
if (NULL == response)
- {
- fclose (file);
- return MHD_NO;
- }
+ {
+ closedir (dir);
+ return MHD_NO;
+ }
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
}
+ }
+ else
+ {
+ response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
+ &file_reader,
+ file,
+ &file_free_callback);
+ if (NULL == response)
+ {
+ fclose (file);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ }
return ret;
}
@@ -186,11 +192,12 @@
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
if (NULL == d)
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/fileserver_example_external_select.c
^
|
@@ -27,7 +27,8 @@
#include <sys/stat.h>
#include <unistd.h>
-#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
static ssize_t
file_reader (void *cls, uint64_t pos, char *buf, size_t max)
@@ -47,72 +48,76 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ size_t *upload_data_size, void **ptr)
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
FILE *file;
int fd;
struct stat buf;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
file = fopen (&url[1], "rb");
if (NULL != file)
+ {
+ fd = fileno (file);
+ if (-1 == fd)
{
- fd = fileno (file);
- if (-1 == fd)
- {
- (void) fclose (file);
- return MHD_NO; /* internal error */
- }
- if ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) )
- {
- /* not a regular file, refuse to serve */
- fclose (file);
- file = NULL;
- }
+ (void) fclose (file);
+ return MHD_NO; /* internal error */
}
-
- if (NULL == file)
+ if ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) )
{
- response = MHD_create_response_from_buffer (strlen (PAGE),
- (void *) PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
- MHD_destroy_response (response);
+ /* not a regular file, refuse to serve */
+ fclose (file);
+ file = NULL;
}
+ }
+
+ if (NULL == file)
+ {
+ response = MHD_create_response_from_buffer (strlen (PAGE),
+ (void *) PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
+ MHD_destroy_response (response);
+ }
else
- {
- response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
- &file_reader,
- file,
- &free_callback);
- if (NULL == response)
- {
- fclose (file);
- return MHD_NO;
- }
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- }
+ {
+ response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
+ &file_reader,
+ file,
+ &free_callback);
+ if (NULL == response)
+ {
+ fclose (file);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ }
return ret;
}
@@ -131,10 +136,10 @@
MHD_UNSIGNED_LONG_LONG mhd_timeout;
if (argc != 3)
- {
- printf ("%s PORT SECONDS-TO-RUN\n", argv[0]);
- return 1;
- }
+ {
+ printf ("%s PORT SECONDS-TO-RUN\n", argv[0]);
+ return 1;
+ }
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
@@ -142,30 +147,30 @@
return 1;
end = time (NULL) + atoi (argv[2]);
while ((t = time (NULL)) < end)
+ {
+ tv.tv_sec = end - t;
+ tv.tv_usec = 0;
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ break; /* fatal internal error */
+ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
+ {
+ if (((MHD_UNSIGNED_LONG_LONG) tv.tv_sec) < mhd_timeout / 1000LL)
+ {
+ tv.tv_sec = mhd_timeout / 1000LL;
+ tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000LL)) * 1000LL;
+ }
+ }
+ if (-1 == select (max + 1, &rs, &ws, &es, &tv))
{
- tv.tv_sec = end - t;
- tv.tv_usec = 0;
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- break; /* fatal internal error */
- if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
- {
- if (((MHD_UNSIGNED_LONG_LONG)tv.tv_sec) < mhd_timeout / 1000LL)
- {
- tv.tv_sec = mhd_timeout / 1000LL;
- tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000LL)) * 1000LL;
- }
- }
- if (-1 == select (max + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- MHD_run (d);
+ if (EINTR != errno)
+ abort ();
}
+ MHD_run (d);
+ }
MHD_stop_daemon (d);
return 0;
}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/http_chunked_compression.c
^
|
@@ -0,0 +1,241 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file http_chunked_compression.c
+ * @brief example for how to compress a chunked HTTP response
+ * @author Silvio Clecio (silvioprog)
+ */
+
+#include "platform.h"
+#include <zlib.h>
+#include <microhttpd.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif /* HAVE_LIMITS_H */
+#include <stddef.h>
+
+#ifndef SSIZE_MAX
+#ifdef __SSIZE_MAX__
+#define SSIZE_MAX __SSIZE_MAX__
+#elif defined(PTRDIFF_MAX)
+#define SSIZE_MAX PTRDIFF_MAX
+#elif defined(INTPTR_MAX)
+#define SSIZE_MAX INTPTR_MAX
+#else
+#define SSIZE_MAX ((ssize_t) (((size_t) -1) >> 1))
+#endif
+#endif /* ! SSIZE_MAX */
+
+#define CHUNK 16384
+
+struct Holder
+{
+ FILE *file;
+ z_stream stream;
+ void *buf;
+};
+
+static enum MHD_Result
+compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset,
+ void **dest, size_t *dest_size,
+ void *tmp)
+{
+ unsigned int have;
+ enum MHD_Result ret;
+ int flush;
+ void *tmp_dest;
+ *dest = NULL;
+ *dest_size = 0;
+ do
+ {
+ if (src_size > CHUNK)
+ {
+ strm->avail_in = CHUNK;
+ src_size -= CHUNK;
+ flush = Z_NO_FLUSH;
+ }
+ else
+ {
+ strm->avail_in = (uInt) src_size;
+ flush = Z_SYNC_FLUSH;
+ }
+ *offset += strm->avail_in;
+ strm->next_in = (Bytef *) src;
+ do
+ {
+ strm->avail_out = CHUNK;
+ strm->next_out = tmp;
+ ret = deflate (strm, flush);
+ have = CHUNK - strm->avail_out;
+ *dest_size += have;
+ tmp_dest = realloc (*dest, *dest_size);
+ if (NULL == tmp_dest)
+ {
+ free (*dest);
+ *dest = NULL;
+ return MHD_NO;
+ }
+ *dest = tmp_dest;
+ memcpy ((*dest) + ((*dest_size) - have), tmp, have);
+ }
+ while (0 == strm->avail_out);
+ }
+ while (flush != Z_SYNC_FLUSH);
+ return (Z_OK == ret) ? MHD_YES : MHD_NO;
+}
+
+
+static ssize_t
+read_cb (void *cls, uint64_t pos, char *mem, size_t size)
+{
+ struct Holder *holder = cls;
+ void *src;
+ void *buf;
+ ssize_t ret;
+ size_t offset;
+
+ if (pos > SSIZE_MAX)
+ return MHD_CONTENT_READER_END_WITH_ERROR;
+ offset = (size_t) pos;
+ src = malloc (size);
+ if (NULL == src)
+ return MHD_CONTENT_READER_END_WITH_ERROR;
+ ret = fread (src, 1, size, holder->file);
+ if (ret < 0)
+ {
+ ret = MHD_CONTENT_READER_END_WITH_ERROR;
+ goto done;
+ }
+ if (0 == ret)
+ {
+ ret = MHD_CONTENT_READER_END_OF_STREAM;
+ goto done;
+ }
+ if (MHD_YES != compress_buf (&holder->stream, src, ret, &offset, &buf, &size,
+ holder->buf))
+ ret = MHD_CONTENT_READER_END_WITH_ERROR;
+ else
+ {
+ memcpy (mem, buf, size);
+ ret = size;
+ }
+ free (buf); /* Buf may be set even on error return. */
+done:
+ free (src);
+ return ret;
+}
+
+
+static void
+free_cb (void *cls)
+{
+ struct Holder *holder = cls;
+ fclose (holder->file);
+ deflateEnd (&holder->stream);
+ free (holder->buf);
+ free (holder);
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const
+ char *method, const char *version,
+ const char *upload_data, size_t *upload_size, void **ptr)
+{
+ struct Holder *holder;
+ struct MHD_Response *res;
+ enum MHD_Result ret;
+ (void) cls;
+ (void) url;
+ (void) method;
+ (void) version;
+ (void) upload_data;
+ (void) upload_size;
+ if (NULL == *ptr)
+ {
+ *ptr = (void *) 1;
+ return MHD_YES;
+ }
+ *ptr = NULL;
+ holder = calloc (1, sizeof (struct Holder));
+ if (! holder)
+ return MHD_NO;
+ holder->file = fopen (__FILE__, "rb");
+ if (NULL == holder->file)
+ goto file_error;
+ ret = deflateInit (&holder->stream, Z_BEST_COMPRESSION);
+ if (ret != Z_OK)
+ goto stream_error;
+ holder->buf = malloc (CHUNK);
+ if (NULL == holder->buf)
+ goto buf_error;
+ res = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024, &read_cb,
+ holder, &free_cb);
+ if (NULL == res)
+ goto error;
+ ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_ENCODING,
+ "deflate");
+ if (MHD_YES != ret)
+ goto res_error;
+ ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_TYPE, "text/x-c");
+ if (MHD_YES != ret)
+ goto res_error;
+ ret = MHD_queue_response (con, MHD_HTTP_OK, res);
+res_error:
+ MHD_destroy_response (res);
+ return ret;
+error:
+ free (holder->buf);
+buf_error:
+ deflateEnd (&holder->stream);
+stream_error:
+ fclose (holder->file);
+file_error:
+ free (holder);
+ return MHD_NO;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ struct MHD_Daemon *d;
+ unsigned int port;
+ if ((argc != 2) ||
+ (1 != sscanf (argv[1], "%u", &port)) ||
+ (UINT16_MAX < port))
+ {
+ fprintf (stderr, "%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ (uint16_t) port, NULL, NULL,
+ &ahc_echo, NULL,
+ MHD_OPTION_END);
+ if (NULL == d)
+ return 1;
+ if (0 == port)
+ MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT, &port);
+ fprintf (stdout,
+ "HTTP server running at http://localhost:%u\n\nPress ENTER to stop the server ...\n",
+ port);
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/http_compression.c
^
|
@@ -0,0 +1,182 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file http_compression.c
+ * @brief minimal example for how to compress HTTP response
+ * @author Silvio Clecio (silvioprog)
+ */
+
+#include "platform.h"
+#include <zlib.h>
+#include <microhttpd.h>
+
+#define PAGE \
+ "<html><head><title>HTTP compression</title></head><body>Hello, " \
+ "hello, hello. This is a 'hello world' message for the world, " \
+ "repeat, for the world.</body></html>"
+
+static enum MHD_Result
+can_compress (struct MHD_Connection *con)
+{
+ const char *ae;
+ const char *de;
+
+ ae = MHD_lookup_connection_value (con,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_ENCODING);
+ if (NULL == ae)
+ return MHD_NO;
+ if (0 == strcmp (ae,
+ "*"))
+ return MHD_YES;
+ de = strstr (ae,
+ "deflate");
+ if (NULL == de)
+ return MHD_NO;
+ if (((de == ae) ||
+ (de[-1] == ',') ||
+ (de[-1] == ' ')) &&
+ ((de[strlen ("deflate")] == '\0') ||
+ (de[strlen ("deflate")] == ',') ||
+ (de[strlen ("deflate")] == ';')))
+ return MHD_YES;
+ return MHD_NO;
+}
+
+
+static enum MHD_Result
+body_compress (void **buf,
+ size_t *buf_size)
+{
+ Bytef *cbuf;
+ uLongf cbuf_size;
+ int ret;
+
+ cbuf_size = compressBound (*buf_size);
+ cbuf = malloc (cbuf_size);
+ if (NULL == cbuf)
+ return MHD_NO;
+ ret = compress (cbuf,
+ &cbuf_size,
+ (const Bytef *) *buf,
+ *buf_size);
+ if ((Z_OK != ret) ||
+ (cbuf_size >= *buf_size))
+ {
+ /* compression failed */
+ free (cbuf);
+ return MHD_NO;
+ }
+ free (*buf);
+ *buf = (void *) cbuf;
+ *buf_size = (size_t) cbuf_size;
+ return MHD_YES;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size, void **ptr)
+{
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ enum MHD_Result comp;
+ size_t body_len;
+ char *body_str;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (method, "GET"))
+ return MHD_NO; /* unexpected method */
+ if (! *ptr)
+ {
+ *ptr = (void *) 1;
+ return MHD_YES;
+ }
+ *ptr = NULL;
+
+ body_str = strdup (PAGE);
+ if (NULL == body_str)
+ {
+ return MHD_NO;
+ }
+ body_len = strlen (body_str);
+ /* try to compress the body */
+ comp = MHD_NO;
+ if (MHD_YES ==
+ can_compress (connection))
+ comp = body_compress ((void **) &body_str,
+ &body_len);
+ response = MHD_create_response_from_buffer (body_len,
+ body_str,
+ MHD_RESPMEM_MUST_FREE);
+ if (NULL == response)
+ {
+ free (body_str);
+ return MHD_NO;
+ }
+
+ if (MHD_YES == comp)
+ {
+ /* Need to indicate to client that body is compressed */
+ if (MHD_NO ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ "deflate"))
+ {
+ MHD_destroy_response (response);
+ return MHD_NO;
+ }
+ }
+ ret = MHD_queue_response (connection,
+ 200,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ struct MHD_Daemon *d;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG,
+ atoi (argv[1]), NULL, NULL,
+ &ahc_echo, NULL,
+ MHD_OPTION_END);
+ if (NULL == d)
+ return 1;
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/https_fileserver_example.c
^
|
@@ -24,7 +24,7 @@
*
* 'http_fileserver_example HTTP-PORT SECONDS-TO-RUN'
*
- * The certificate & key are required by the server to operate, Omitting the
+ * The certificate & key are required by the server to operate, omitting the
* path arguments will cause the server to use the hard coded example certificate & key.
*
* 'certtool' may be used to generate these if required.
@@ -35,65 +35,81 @@
#include "platform.h"
#include <microhttpd.h>
#include <sys/stat.h>
-#include <gnutls/gnutls.h>
-#include <gcrypt.h>
#define BUF_SIZE 1024
#define MAX_URL_LEN 255
-// TODO remove if unused
+/* TODO remove if unused */
#define CAFILE "ca.pem"
#define CRLFILE "crl.pem"
-#define EMPTY_PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
-
-/* Test Certificate */
-const char cert_pem[] =
- "-----BEGIN CERTIFICATE-----\n"
- "MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0\n"
- "MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC\n"
- "AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X\n"
- "fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud\n"
- "3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/\n"
- "GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv\n"
- "rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh\n"
- "siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O\n"
- "BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2\n"
- "RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN\n"
- "8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/\n"
- "0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe\n"
- "JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3\n"
- "OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV\n"
- "RhZvQx74NQnS6g==\n" "-----END CERTIFICATE-----\n";
+#define EMPTY_PAGE \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
+/* test server key */
const char key_pem[] =
- "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf\n"
- "qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I\n"
- "niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+\n"
- "faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx\n"
- "7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ\n"
- "vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj\n"
- "lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R\n"
- "EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l\n"
- "/5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx\n"
- "u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/\n"
- "dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo\n"
- "32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc\n"
- "+JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd\n"
- "RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6\n"
- "OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob\n"
- "XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF\n"
- "hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae\n"
- "SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b\n"
- "AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH\n"
- "6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3\n"
- "QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG\n"
- "7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj\n"
- "P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9\n"
- "/Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC\n"
- "eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx\n"
- "-----END RSA PRIVATE KEY-----\n";
+ "-----BEGIN PRIVATE KEY-----\n\
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrm8uH8V0P2Xbl\n\
+HCMq6PTIphDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZ\n\
+Vyg4ksOA7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd\n\
+6mi978n//bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5yg\n\
+CR99TDDHZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/Lni\n\
+CGO9uXGOgZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF\n\
+1N8GZZC7AgMBAAECggEAc0F/wR3qUurLX7U2KWuse9aNHFb84mBfCAw3hj7ddFEl\n\
+wto7EB50MA0KY4OI8u6fQH4E8zINoAciDzLqYJSxmbZhC1N5YX/Yc3qtZdB2b5tj\n\
+anbsSQqVo8YVPVDU4bCsG9vhArdd4JdCnD0DfA3ArZ3JAPwHsB4Ks1icLSOIGz0/\n\
+JvOZEryJBdwM6SKbzLMqVOGmYDiY6s7UpJ0rg3cOPqhdg5xv8XZATqXISU0mLBcq\n\
+RiS7lHZERASYON2rpznhBiCtikOcr/duQhvZ1uDSGfDzDJil+1hdS3RouS9WZCIe\n\
+p3CtvZhPLmv6kFg9YE+AovDwOOwNr0no3H9oJA2FgQKBgQDSWrE/MRMRpFJFBxxC\n\
+YckC2v8Y+7sVSMbFNq/0j2eRTql+8AeZBbAoGU4QHUcylCBkv33zDYRY52xNo32E\n\
+8mmH2O/pIcYy0LafrVZHdulf+fxybncObidxmmjR9C8aLzwRuIMtABz4simaQcBD\n\
+RhZJ1YCqVkfMr/PlbLzvC8V+FwKBgQDQ2MF/Yz/p7QEDHpfKdtx7+yK6i8IM+V8l\n\
+d2OuscNkQQywCVqE2vyRZJbjU9y+Om7alNKFPhhBzavdOxNWXGXmlBIlvo3v6M++\n\
+fTixza77LxHvbghH0ykplSwGh30vpHtvoxsRS5nRFxmsVK9jNYYT/Aes+J6MXlq7\n\
+PYAiZVQs/QKBgFKYY8JhPZCOyfLqsNDr3matoL6pkTLxSYMETyCi8lKe5XS/QOx3\n\
+zExia0FujZcxjGqiugymgRH7hI4TpOR/3qoFp2YN6enoA908zYTwDwCtgs9Xyo2y\n\
++O/lZkUSMTCB3X9DyNXxlm6cXjOAn8KKkZPaLlQz3qtjZ0vtX14pbBlvAoGBAKw0\n\
+vsCifvYNZhNDa5gXkFBu0MEPMm/uQ+Up37kRfPKyrJqO6+O2iiH81moWIWN93SBB\n\
+LKGPhQLlazxdVOGWCLQrDhevW2wiBQKmUFRULF+T/W72xL8sv7k49ndfyvq43ss7\n\
+q7sEIo4FRTcTERd179uUqmOXEWze9GOGH5y8/r6lAoGAG2YyqRWF+yxKlgR71b1Q\n\
+Zxv53WgXOUwemGRbXxE4g3gHpW5k9zWh4QTkbd0lDD+SQ0DBwZl/x/FWj43jUS+i\n\
+a5UojDUx8nYgjiAO7kppMlX3ZaJD1DkwEz+4HW9oPmOFt8smvuTVt0mm6tpmQdRA\n\
+yLwgQzGDGVJB6ETVJS7cwWs=\n\
+-----END PRIVATE KEY-----";
+
+/* test server CA signed certificates */
+const char cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIFaTCCA1GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MjFaGA8yMTIxMDMxMzE3\n\
+MzYyMVowgYcxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMRQwEgYDVQQDDAt0\n\
+ZXN0LXNlcnZlcjEjMCEGA1UdEQwaRE5TOmxvY2FsaG9zdCxJUDoxMjcuMC4wLjEw\n\
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrm8uH8V0P2XblHCMq6PTI\n\
+phDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZVyg4ksOA\n\
+7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd6mi978n/\n\
+/bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5ygCR99TDDH\n\
+ZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/LniCGO9uXGO\n\
+gZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF1N8GZZC7\n\
+AgMBAAGjgeEwgd4wCwYDVR0PBAQDAgWgMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n\
+BAwwCgYIKwYBBQUHAwEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAA\n\
+AAAAAAAAAAAAAAABMB0GA1UdDgQWBBRifkHd2xWI51NhnH8sL66K8EedpjAoBglg\n\
+hkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBkIHNlcnZlcjARBglghkgBhvhC\n\
+AQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOFNd0arI3/QB3W6SwwDQYJKoZI\n\
+hvcNAQELBQADggIBAJoIyNrnwQ+7WcJDaBjjuwSH0ORuK+E3zRI3+nDde08gyfeG\n\
+K4QozT2L574WzadTVLSiin9lRShYlp0nr60pmUb9+SKE0O7Cx+rYV0Rfu0KLYsYh\n\
+sAkb9J9t1fdIt54fXNcUtvfGPyM2lEI0KxMCGNV2wXDnwzdSNIU6Nk457MntfZdi\n\
+r1ISnS6fLd0BIKIGxfCFb10CexhNOSaExgpp1bxZovdYaQWggL0u8eC8j00sJ1C5\n\
+Qo4gQ1TQsead6zMs6m19TPLlV7hS+hfXj7yeJ/TTUj69bCjTIMp6HCFnfQbD84BI\n\
+HZDKk4Tob9vBRCKbY58kNXHyQ4nxvSCBlKI03VJjvzpsKTI/vW9JBivtnYtMbMl9\n\
+ouZal/IVsNqRCeiMTLky62qrFhZr2DHgPG5VcOGQ4y0X4vOgM9n/MMOGWcNBByLX\n\
+b5ZaYr7DPCcz9dYZgEbwXj8wnuAzM1sJ2igwTmO/vQsn1G2Q/h/JB471CD1avuuI\n\
+awKRqhU2KhYVrwo7ahJkPV9Lm6eoavq2Tu+e1o4qAFhPLMy/6F+bZmK6GfHMvP+L\n\
+v+GOQdUJ/vMMus/HB5N3cUZsu9rGnCCVgPW7pkHrp5bRtuVzBT78ISsxkGnOhfT7\n\
+6Kp7ApvfEX6/Y/vbDFBC4kyAvEIZ+F8AUkbvZ0+k8j5xlarNd6TQ3slEGi6O\n\
+-----END CERTIFICATE-----";
static ssize_t
file_reader (void *cls, uint64_t pos, char *buf, size_t max)
@@ -104,6 +120,7 @@
return fread (buf, 1, max, file);
}
+
static void
file_free_callback (void *cls)
{
@@ -111,72 +128,77 @@
fclose (file);
}
+
/* HTTP access handler call back */
-static int
+static enum MHD_Result
http_ahc (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
- size_t *upload_data_size, void **ptr)
+ size_t *upload_data_size, void **ptr)
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
FILE *file;
int fd;
struct stat buf;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
file = fopen (&url[1], "rb");
if (NULL != file)
+ {
+ fd = fileno (file);
+ if (-1 == fd)
{
- fd = fileno (file);
- if (-1 == fd)
- {
- (void) fclose (file);
- return MHD_NO; /* internal error */
- }
- if ( (0 != fstat (fd, &buf)) ||
- (! S_ISREG (buf.st_mode)) )
- {
- /* not a regular file, refuse to serve */
- fclose (file);
- file = NULL;
- }
+ (void) fclose (file);
+ return MHD_NO; /* internal error */
}
-
- if (NULL == file)
+ if ( (0 != fstat (fd, &buf)) ||
+ (! S_ISREG (buf.st_mode)) )
{
- response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE),
- (void *) EMPTY_PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
- MHD_destroy_response (response);
+ /* not a regular file, refuse to serve */
+ fclose (file);
+ file = NULL;
}
+ }
+
+ if (NULL == file)
+ {
+ response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE),
+ (void *) EMPTY_PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
+ MHD_destroy_response (response);
+ }
else
- {
- response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
- &file_reader, file,
- &file_free_callback);
- if (NULL == response)
- {
- fclose (file);
- return MHD_NO;
- }
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- }
+ {
+ response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
+ &file_reader, file,
+ &file_free_callback);
+ if (NULL == response)
+ {
+ fclose (file);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ }
return ret;
}
@@ -185,38 +207,43 @@
main (int argc, char *const *argv)
{
struct MHD_Daemon *TLS_daemon;
+ int port;
- if (argc == 2)
- {
- /* TODO check if this is truly necessary - disallow usage of the blocking /dev/random */
- /* gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); */
- TLS_daemon =
- MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG |
- MHD_USE_TLS, atoi (argv[1]), NULL, NULL, &http_ahc,
- NULL, MHD_OPTION_CONNECTION_TIMEOUT, 256,
- MHD_OPTION_HTTPS_MEM_KEY, key_pem,
- MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
- MHD_OPTION_END);
- }
- else
- {
- printf ("Usage: %s HTTP-PORT\n", argv[0]);
- return 1;
- }
-
- if (TLS_daemon == NULL)
- {
- fprintf (stderr, "Error: failed to start TLS_daemon\n");
- return 1;
- }
- else
- {
- printf ("MHD daemon listening on port %d\n", atoi (argv[1]));
- }
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ port = atoi (argv[1]);
+ if ( (1 > port) ||
+ (port > UINT16_MAX) )
+ {
+ fprintf (stderr,
+ "Port must be a number between 1 and 65535\n");
+ return 1;
+ }
+
+ TLS_daemon =
+ MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | MHD_USE_TLS,
+ (uint16_t) port,
+ NULL, NULL,
+ &http_ahc, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, 256,
+ MHD_OPTION_HTTPS_MEM_KEY, key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
+ MHD_OPTION_END);
+ if (NULL == TLS_daemon)
+ {
+ fprintf (stderr, "Error: failed to start TLS_daemon.\n");
+ return 1;
+ }
+ printf ("MHD daemon listening on port %u\n",
+ (unsigned int) port);
(void) getc (stdin);
MHD_stop_daemon (TLS_daemon);
-
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/minimal_example.c
^
|
@@ -25,58 +25,70 @@
#include "platform.h"
#include <microhttpd.h>
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
- const char *upload_data, size_t *upload_data_size, void **ptr)
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
{
static int aptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (me),
- (void *) me,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ (void *) me,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
+
int
-main (int argc, char *const *argv)
+main (int argc,
+ char *const *argv)
{
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- // MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL,
- // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- atoi (argv[1]),
- NULL, NULL, &ahc_echo, PAGE,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
- MHD_OPTION_END);
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, PAGE,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/minimal_example_comet.c
^
|
@@ -28,6 +28,8 @@
static ssize_t
data_generator (void *cls, uint64_t pos, char *buf, size_t max)
{
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) pos; /* Unused. Silent compiler warning. */
if (max < 80)
return 0;
memset (buf, 'A', max - 1);
@@ -35,7 +37,8 @@
return 80;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -45,16 +48,21 @@
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
80,
@@ -64,17 +72,19 @@
return ret;
}
+
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
if (d == NULL)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/minimal_example_empty.c
^
|
@@ -0,0 +1,95 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file minimal_example.c
+ * @brief minimal example for how to use libmicrohttpd
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include <microhttpd.h>
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
+{
+ static int aptr;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (method, "GET"))
+ return MHD_NO; /* unexpected method */
+ if (&aptr != *ptr)
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
+ response = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ struct MHD_Daemon *d;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/minimal_example_empty_tls.c
^
|
@@ -0,0 +1,166 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file minimal_example_empty_ssl.c
+ * @brief minimal example for how to use libmicrohttpd
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include <microhttpd.h>
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
+{
+ static int aptr;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (method, "GET"))
+ return MHD_NO; /* unexpected method */
+ if (&aptr != *ptr)
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
+ response = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+/* test server key */
+const char srv_signed_key_pem[] =
+ "-----BEGIN PRIVATE KEY-----\n\
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrm8uH8V0P2Xbl\n\
+HCMq6PTIphDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZ\n\
+Vyg4ksOA7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd\n\
+6mi978n//bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5yg\n\
+CR99TDDHZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/Lni\n\
+CGO9uXGOgZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF\n\
+1N8GZZC7AgMBAAECggEAc0F/wR3qUurLX7U2KWuse9aNHFb84mBfCAw3hj7ddFEl\n\
+wto7EB50MA0KY4OI8u6fQH4E8zINoAciDzLqYJSxmbZhC1N5YX/Yc3qtZdB2b5tj\n\
+anbsSQqVo8YVPVDU4bCsG9vhArdd4JdCnD0DfA3ArZ3JAPwHsB4Ks1icLSOIGz0/\n\
+JvOZEryJBdwM6SKbzLMqVOGmYDiY6s7UpJ0rg3cOPqhdg5xv8XZATqXISU0mLBcq\n\
+RiS7lHZERASYON2rpznhBiCtikOcr/duQhvZ1uDSGfDzDJil+1hdS3RouS9WZCIe\n\
+p3CtvZhPLmv6kFg9YE+AovDwOOwNr0no3H9oJA2FgQKBgQDSWrE/MRMRpFJFBxxC\n\
+YckC2v8Y+7sVSMbFNq/0j2eRTql+8AeZBbAoGU4QHUcylCBkv33zDYRY52xNo32E\n\
+8mmH2O/pIcYy0LafrVZHdulf+fxybncObidxmmjR9C8aLzwRuIMtABz4simaQcBD\n\
+RhZJ1YCqVkfMr/PlbLzvC8V+FwKBgQDQ2MF/Yz/p7QEDHpfKdtx7+yK6i8IM+V8l\n\
+d2OuscNkQQywCVqE2vyRZJbjU9y+Om7alNKFPhhBzavdOxNWXGXmlBIlvo3v6M++\n\
+fTixza77LxHvbghH0ykplSwGh30vpHtvoxsRS5nRFxmsVK9jNYYT/Aes+J6MXlq7\n\
+PYAiZVQs/QKBgFKYY8JhPZCOyfLqsNDr3matoL6pkTLxSYMETyCi8lKe5XS/QOx3\n\
+zExia0FujZcxjGqiugymgRH7hI4TpOR/3qoFp2YN6enoA908zYTwDwCtgs9Xyo2y\n\
++O/lZkUSMTCB3X9DyNXxlm6cXjOAn8KKkZPaLlQz3qtjZ0vtX14pbBlvAoGBAKw0\n\
+vsCifvYNZhNDa5gXkFBu0MEPMm/uQ+Up37kRfPKyrJqO6+O2iiH81moWIWN93SBB\n\
+LKGPhQLlazxdVOGWCLQrDhevW2wiBQKmUFRULF+T/W72xL8sv7k49ndfyvq43ss7\n\
+q7sEIo4FRTcTERd179uUqmOXEWze9GOGH5y8/r6lAoGAG2YyqRWF+yxKlgR71b1Q\n\
+Zxv53WgXOUwemGRbXxE4g3gHpW5k9zWh4QTkbd0lDD+SQ0DBwZl/x/FWj43jUS+i\n\
+a5UojDUx8nYgjiAO7kppMlX3ZaJD1DkwEz+4HW9oPmOFt8smvuTVt0mm6tpmQdRA\n\
+yLwgQzGDGVJB6ETVJS7cwWs=\n\
+-----END PRIVATE KEY-----";
+
+/* test server CA signed certificates */
+const char srv_signed_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIFaTCCA1GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MjFaGA8yMTIxMDMxMzE3\n\
+MzYyMVowgYcxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMRQwEgYDVQQDDAt0\n\
+ZXN0LXNlcnZlcjEjMCEGA1UdEQwaRE5TOmxvY2FsaG9zdCxJUDoxMjcuMC4wLjEw\n\
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrm8uH8V0P2XblHCMq6PTI\n\
+phDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZVyg4ksOA\n\
+7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd6mi978n/\n\
+/bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5ygCR99TDDH\n\
+ZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/LniCGO9uXGO\n\
+gZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF1N8GZZC7\n\
+AgMBAAGjgeEwgd4wCwYDVR0PBAQDAgWgMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n\
+BAwwCgYIKwYBBQUHAwEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAA\n\
+AAAAAAAAAAAAAAABMB0GA1UdDgQWBBRifkHd2xWI51NhnH8sL66K8EedpjAoBglg\n\
+hkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBkIHNlcnZlcjARBglghkgBhvhC\n\
+AQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOFNd0arI3/QB3W6SwwDQYJKoZI\n\
+hvcNAQELBQADggIBAJoIyNrnwQ+7WcJDaBjjuwSH0ORuK+E3zRI3+nDde08gyfeG\n\
+K4QozT2L574WzadTVLSiin9lRShYlp0nr60pmUb9+SKE0O7Cx+rYV0Rfu0KLYsYh\n\
+sAkb9J9t1fdIt54fXNcUtvfGPyM2lEI0KxMCGNV2wXDnwzdSNIU6Nk457MntfZdi\n\
+r1ISnS6fLd0BIKIGxfCFb10CexhNOSaExgpp1bxZovdYaQWggL0u8eC8j00sJ1C5\n\
+Qo4gQ1TQsead6zMs6m19TPLlV7hS+hfXj7yeJ/TTUj69bCjTIMp6HCFnfQbD84BI\n\
+HZDKk4Tob9vBRCKbY58kNXHyQ4nxvSCBlKI03VJjvzpsKTI/vW9JBivtnYtMbMl9\n\
+ouZal/IVsNqRCeiMTLky62qrFhZr2DHgPG5VcOGQ4y0X4vOgM9n/MMOGWcNBByLX\n\
+b5ZaYr7DPCcz9dYZgEbwXj8wnuAzM1sJ2igwTmO/vQsn1G2Q/h/JB471CD1avuuI\n\
+awKRqhU2KhYVrwo7ahJkPV9Lm6eoavq2Tu+e1o4qAFhPLMy/6F+bZmK6GfHMvP+L\n\
+v+GOQdUJ/vMMus/HB5N3cUZsu9rGnCCVgPW7pkHrp5bRtuVzBT78ISsxkGnOhfT7\n\
+6Kp7ApvfEX6/Y/vbDFBC4kyAvEIZ+F8AUkbvZ0+k8j5xlarNd6TQ3slEGi6O\n\
+-----END CERTIFICATE-----";
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ struct MHD_Daemon *d;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | MHD_USE_TLS,
+ /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
+ /* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ /* Optionally, the gnutls_load_file() can be used to
+ load the key and the certificate from file. */
+ MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/msgs_i18n.c
^
|
@@ -24,7 +24,7 @@
*/
/*
- * suposing you are in Brazil:
+ * supposing you are in Brazil:
*
* # generate the PO file
* $ msginit --input=po/libmicrohttpd.pot --locale=pt_BR --output=libmicrohttpd.po
@@ -45,29 +45,29 @@
static int
ahc_echo (void *cls,
- struct MHD_Connection *cnc,
- const char *url,
- const char *mt,
- const char *ver,
- const char *upd,
- size_t *upsz,
- void **ptr)
-{
+ struct MHD_Connection *cnc,
+ const char *url,
+ const char *mt,
+ const char *ver,
+ const char *upd,
+ size_t *upsz,
+ void **ptr)
+{
return MHD_NO;
}
static void
error_handler (void *cls,
- const char *fm,
- va_list ap)
+ const char *fm,
+ va_list ap)
{
/* Here we do the translation using GNU gettext.
As the error message is from libmicrohttpd, we specify
"libmicrohttpd" as the translation domain here. */
vprintf (dgettext ("libmicrohttpd",
- fm),
- ap);
+ fm),
+ ap);
}
@@ -75,21 +75,22 @@
main (int argc,
char **argv)
{
- setlocale(LC_ALL, "");
+ setlocale (LC_ALL, "");
- /* The example uses PO files in the directory
+ /* The example uses PO files in the directory
"libmicrohttpd/src/examples/locale". This
needs to be adapted to match
where the MHD PO files are installed. */
bindtextdomain ("libmicrohttpd",
- "locale");
- MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_FEATURE_MESSAGES | MHD_USE_ERROR_LOG,
- 8080,
- NULL, NULL,
- &ahc_echo, NULL,
- MHD_OPTION_EXTERNAL_LOGGER, &error_handler, NULL,
- 99999 /* invalid option, to raise the error
- "Invalid option ..." which we are going
- to translate */);
+ "locale");
+ MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_FEATURE_MESSAGES
+ | MHD_USE_ERROR_LOG,
+ 8080,
+ NULL, NULL,
+ &ahc_echo, NULL,
+ MHD_OPTION_EXTERNAL_LOGGER, &error_handler, NULL,
+ 99999 /* invalid option, to raise the error
+ "Invalid option ..." which we are going
+ to translate */);
return 1; /* This program won't "succeed"... */
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/post_example.c
^
|
@@ -32,32 +32,38 @@
/**
* Invalid method page.
*/
-#define METHOD_ERROR "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
+#define METHOD_ERROR \
+ "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
/**
* Invalid URL page.
*/
-#define NOT_FOUND_ERROR "<html><head><title>Not found</title></head><body>Go away.</body></html>"
+#define NOT_FOUND_ERROR \
+ "<html><head><title>Not found</title></head><body>Go away.</body></html>"
/**
* Front page. (/)
*/
-#define MAIN_PAGE "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
+#define MAIN_PAGE \
+ "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></form></body></html>"
/**
* Second page. (/2)
*/
-#define SECOND_PAGE "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
+#define SECOND_PAGE \
+ "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></form></body></html>"
/**
* Second page (/S)
*/
-#define SUBMIT_PAGE "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>"
+#define SUBMIT_PAGE \
+ "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></form></body></html>"
/**
* Last page.
*/
-#define LAST_PAGE "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
+#define LAST_PAGE \
+ "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
/**
* Name of our cookie.
@@ -137,8 +143,6 @@
static struct Session *sessions;
-
-
/**
* Return the session handle for this connection, or
* create one if this is a new user.
@@ -150,40 +154,40 @@
const char *cookie;
cookie = MHD_lookup_connection_value (connection,
- MHD_COOKIE_KIND,
- COOKIE_NAME);
+ MHD_COOKIE_KIND,
+ COOKIE_NAME);
if (cookie != NULL)
+ {
+ /* find existing session */
+ ret = sessions;
+ while (NULL != ret)
{
- /* find existing session */
- ret = sessions;
- while (NULL != ret)
- {
- if (0 == strcmp (cookie, ret->sid))
- break;
- ret = ret->next;
- }
- if (NULL != ret)
- {
- ret->rc++;
- return ret;
- }
+ if (0 == strcmp (cookie, ret->sid))
+ break;
+ ret = ret->next;
}
+ if (NULL != ret)
+ {
+ ret->rc++;
+ return ret;
+ }
+ }
/* create fresh session */
ret = calloc (1, sizeof (struct Session));
if (NULL == ret)
- {
- fprintf (stderr, "calloc error: %s\n", strerror (errno));
- return NULL;
- }
+ {
+ fprintf (stderr, "calloc error: %s\n", strerror (errno));
+ return NULL;
+ }
/* not a super-secure way to generate a random session ID,
but should do for a simple example... */
snprintf (ret->sid,
- sizeof (ret->sid),
- "%X%X%X%X",
- (unsigned int) rand (),
- (unsigned int) rand (),
- (unsigned int) rand (),
- (unsigned int) rand ());
+ sizeof (ret->sid),
+ "%X%X%X%X",
+ (unsigned int) rand (),
+ (unsigned int) rand (),
+ (unsigned int) rand (),
+ (unsigned int) rand ());
ret->rc++;
ret->start = time (NULL);
ret->next = sessions;
@@ -201,10 +205,10 @@
* @param connection connection to process
* @param MHD_YES on success, MHD_NO on failure
*/
-typedef int (*PageHandler)(const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection);
+typedef enum MHD_Result (*PageHandler)(const void *cls,
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection);
/**
@@ -242,22 +246,22 @@
*/
static void
add_session_cookie (struct Session *session,
- struct MHD_Response *response)
+ struct MHD_Response *response)
{
char cstr[256];
snprintf (cstr,
- sizeof (cstr),
- "%s=%s",
- COOKIE_NAME,
- session->sid);
+ sizeof (cstr),
+ "%s=%s",
+ COOKIE_NAME,
+ session->sid);
if (MHD_NO ==
MHD_add_response_header (response,
- MHD_HTTP_HEADER_SET_COOKIE,
- cstr))
- {
- fprintf (stderr,
- "Failed to set session cookie header!\n");
- }
+ MHD_HTTP_HEADER_SET_COOKIE,
+ cstr))
+ {
+ fprintf (stderr,
+ "Failed to set session cookie header!\n");
+ }
}
@@ -270,29 +274,29 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
serve_simple_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
const char *form = cls;
struct MHD_Response *response;
/* return static form */
response = MHD_create_response_from_buffer (strlen (form),
- (void *) form,
- MHD_RESPMEM_PERSISTENT);
+ (void *) form,
+ MHD_RESPMEM_PERSISTENT);
if (NULL == response)
return MHD_NO;
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -306,36 +310,42 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
fill_v1_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
+ size_t slen;
char *reply;
struct MHD_Response *response;
+ (void) cls; /* Unused. Silent compiler warning. */
- reply = malloc (strlen (MAIN_PAGE) + strlen (session->value_1) + 1);
+ slen = strlen (MAIN_PAGE) + strlen (session->value_1);
+ reply = malloc (slen + 1);
if (NULL == reply)
return MHD_NO;
snprintf (reply,
- strlen (MAIN_PAGE) + strlen (session->value_1) + 1,
- MAIN_PAGE,
- session->value_1);
+ slen + 1,
+ MAIN_PAGE,
+ session->value_1);
/* return static form */
- response = MHD_create_response_from_buffer (strlen (reply),
- (void *) reply,
- MHD_RESPMEM_MUST_FREE);
+ response = MHD_create_response_from_buffer (slen,
+ (void *) reply,
+ MHD_RESPMEM_MUST_FREE);
if (NULL == response)
+ {
+ free (reply);
return MHD_NO;
+ }
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -349,37 +359,44 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
fill_v1_v2_form (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
char *reply;
struct MHD_Response *response;
+ size_t slen;
+ (void) cls; /* Unused. Silent compiler warning. */
- reply = malloc (strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (session->value_2) + 1);
+ slen = strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (
+ session->value_2);
+ reply = malloc (slen + 1);
if (NULL == reply)
return MHD_NO;
snprintf (reply,
- strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (session->value_2) + 1,
- SECOND_PAGE,
- session->value_1,
+ slen + 1,
+ SECOND_PAGE,
+ session->value_1,
session->value_2);
/* return static form */
- response = MHD_create_response_from_buffer (strlen (reply),
- (void *) reply,
- MHD_RESPMEM_MUST_FREE);
+ response = MHD_create_response_from_buffer (slen,
+ (void *) reply,
+ MHD_RESPMEM_MUST_FREE);
if (NULL == response)
+ {
+ free (reply);
return MHD_NO;
+ }
add_session_cookie (session, response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -393,27 +410,29 @@
* @param session session handle
* @param connection connection to use
*/
-static int
+static enum MHD_Result
not_found_page (const void *cls,
- const char *mime,
- struct Session *session,
- struct MHD_Connection *connection)
+ const char *mime,
+ struct Session *session,
+ struct MHD_Connection *connection)
{
- int ret;
+ enum MHD_Result ret;
struct MHD_Response *response;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) session; /* Unused. Silent compiler warning. */
/* unsupported HTTP method */
response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR),
- (void *) NOT_FOUND_ERROR,
- MHD_RESPMEM_PERSISTENT);
+ (void *) NOT_FOUND_ERROR,
+ MHD_RESPMEM_PERSISTENT);
if (NULL == response)
return MHD_NO;
ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_FOUND,
- response);
+ MHD_HTTP_NOT_FOUND,
+ response);
MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- mime);
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ mime);
MHD_destroy_response (response);
return ret;
}
@@ -422,15 +441,13 @@
/**
* List of all pages served by this HTTP server.
*/
-static struct Page pages[] =
- {
- { "/", "text/html", &fill_v1_form, NULL },
- { "/2", "text/html", &fill_v1_v2_form, NULL },
- { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
- { "/F", "text/html", &serve_simple_form, LAST_PAGE },
- { NULL, NULL, ¬_found_page, NULL } /* 404 */
- };
-
+static struct Page pages[] = {
+ { "/", "text/html", &fill_v1_form, NULL },
+ { "/2", "text/html", &fill_v1_v2_form, NULL },
+ { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
+ { "/F", "text/html", &serve_simple_form, LAST_PAGE },
+ { NULL, NULL, ¬_found_page, NULL } /* 404 */
+};
/**
@@ -452,47 +469,51 @@
* @return MHD_YES to continue iterating,
* MHD_NO to abort the iteration
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *filename,
- const char *content_type,
- const char *transfer_encoding,
- const char *data, uint64_t off, size_t size)
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data, uint64_t off, size_t size)
{
struct Request *request = cls;
struct Session *session = request->session;
+ (void) kind; /* Unused. Silent compiler warning. */
+ (void) filename; /* Unused. Silent compiler warning. */
+ (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; /* Unused. Silent compiler warning. */
if (0 == strcmp ("DONE", key))
- {
- fprintf (stdout,
- "Session `%s' submitted `%s', `%s'\n",
- session->sid,
- session->value_1,
- session->value_2);
- return MHD_YES;
- }
+ {
+ fprintf (stdout,
+ "Session `%s' submitted `%s', `%s'\n",
+ session->sid,
+ session->value_1,
+ session->value_2);
+ return MHD_YES;
+ }
if (0 == strcmp ("v1", key))
- {
- if (size + off >= sizeof(session->value_1))
- size = sizeof (session->value_1) - off - 1;
- memcpy (&session->value_1[off],
- data,
- size);
- session->value_1[size+off] = '\0';
- return MHD_YES;
- }
+ {
+ if (size + off >= sizeof(session->value_1))
+ size = sizeof (session->value_1) - off - 1;
+ memcpy (&session->value_1[off],
+ data,
+ size);
+ session->value_1[size + off] = '\0';
+ return MHD_YES;
+ }
if (0 == strcmp ("v2", key))
- {
- if (size + off >= sizeof(session->value_2))
- size = sizeof (session->value_2) - off - 1;
- memcpy (&session->value_2[off],
- data,
- size);
- session->value_2[size+off] = '\0';
- return MHD_YES;
- }
+ {
+ if (size + off >= sizeof(session->value_2))
+ size = sizeof (session->value_2) - off - 1;
+ memcpy (&session->value_2[off],
+ data,
+ size);
+ session->value_2[size + off] = '\0';
+ return MHD_YES;
+ }
fprintf (stderr,
"Unsupported form value `%s'\n",
key);
@@ -530,102 +551,104 @@
* can be set with the MHD_OPTION_NOTIFY_COMPLETED).
* Initially, <tt>*con_cls</tt> will be NULL.
* @return MHS_YES if the connection was handled successfully,
- * MHS_NO if the socket must be closed due to a serios
+ * MHS_NO if the socket must be closed due to a serious
* error while handling the request
*/
-static int
+static enum MHD_Result
create_response (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **ptr)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
{
struct MHD_Response *response;
struct Request *request;
struct Session *session;
- int ret;
+ enum MHD_Result ret;
unsigned int i;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
request = *ptr;
if (NULL == request)
+ {
+ request = calloc (1, sizeof (struct Request));
+ if (NULL == request)
{
- request = calloc (1, sizeof (struct Request));
- if (NULL == request)
- {
- fprintf (stderr, "calloc error: %s\n", strerror (errno));
- return MHD_NO;
- }
- *ptr = request;
- if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
- {
- request->pp = MHD_create_post_processor (connection, 1024,
- &post_iterator, request);
- if (NULL == request->pp)
- {
- fprintf (stderr, "Failed to setup post processor for `%s'\n",
- url);
- return MHD_NO; /* internal error */
- }
- }
- return MHD_YES;
+ fprintf (stderr, "calloc error: %s\n", strerror (errno));
+ return MHD_NO;
+ }
+ *ptr = request;
+ if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+ {
+ request->pp = MHD_create_post_processor (connection, 1024,
+ &post_iterator, request);
+ if (NULL == request->pp)
+ {
+ fprintf (stderr, "Failed to setup post processor for `%s'\n",
+ url);
+ return MHD_NO; /* internal error */
+ }
}
+ return MHD_YES;
+ }
if (NULL == request->session)
+ {
+ request->session = get_session (connection);
+ if (NULL == request->session)
{
- request->session = get_session (connection);
- if (NULL == request->session)
- {
- fprintf (stderr, "Failed to setup session for `%s'\n",
- url);
- return MHD_NO; /* internal error */
- }
+ fprintf (stderr, "Failed to setup session for `%s'\n",
+ url);
+ return MHD_NO; /* internal error */
}
+ }
session = request->session;
session->start = time (NULL);
if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+ {
+ /* evaluate POST data */
+ MHD_post_process (request->pp,
+ upload_data,
+ *upload_data_size);
+ if (0 != *upload_data_size)
{
- /* evaluate POST data */
- MHD_post_process (request->pp,
- upload_data,
- *upload_data_size);
- if (0 != *upload_data_size)
- {
- *upload_data_size = 0;
- return MHD_YES;
- }
- /* done with POST data, serve response */
- MHD_destroy_post_processor (request->pp);
- request->pp = NULL;
- method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
- if (NULL != request->post_url)
- url = request->post_url;
+ *upload_data_size = 0;
+ return MHD_YES;
}
+ /* done with POST data, serve response */
+ MHD_destroy_post_processor (request->pp);
+ request->pp = NULL;
+ method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
+ if (NULL != request->post_url)
+ url = request->post_url;
+ }
if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
(0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
- {
- /* find out which page to serve */
- i=0;
- while ( (pages[i].url != NULL) &&
- (0 != strcmp (pages[i].url, url)) )
- i++;
- ret = pages[i].handler (pages[i].handler_cls,
- pages[i].mime,
- session, connection);
- if (ret != MHD_YES)
- fprintf (stderr, "Failed to create page for `%s'\n",
- url);
- return ret;
- }
+ {
+ /* find out which page to serve */
+ i = 0;
+ while ( (pages[i].url != NULL) &&
+ (0 != strcmp (pages[i].url, url)) )
+ i++;
+ ret = pages[i].handler (pages[i].handler_cls,
+ pages[i].mime,
+ session, connection);
+ if (ret != MHD_YES)
+ fprintf (stderr, "Failed to create page for `%s'\n",
+ url);
+ return ret;
+ }
/* unsupported HTTP method */
response = MHD_create_response_from_buffer (strlen (METHOD_ERROR),
- (void *) METHOD_ERROR,
- MHD_RESPMEM_PERSISTENT);
+ (void *) METHOD_ERROR,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection,
- MHD_HTTP_NOT_ACCEPTABLE,
- response);
+ MHD_HTTP_NOT_ACCEPTABLE,
+ response);
MHD_destroy_response (response);
return ret;
}
@@ -642,11 +665,14 @@
*/
static void
request_completed_callback (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct Request *request = *con_cls;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) toe; /* Unused. Silent compiler warning. */
if (NULL == request)
return;
@@ -674,21 +700,21 @@
prev = NULL;
pos = sessions;
while (NULL != pos)
+ {
+ next = pos->next;
+ if (now - pos->start > 60 * 60)
{
- next = pos->next;
- if (now - pos->start > 60 * 60)
- {
- /* expire sessions after 1h */
- if (NULL == prev)
- sessions = pos->next;
- else
- prev->next = next;
- free (pos);
- }
+ /* expire sessions after 1h */
+ if (NULL == prev)
+ sessions = pos->next;
else
- prev = pos;
- pos = next;
+ prev->next = next;
+ free (pos);
}
+ else
+ prev = pos;
+ pos = next;
+ }
}
@@ -709,45 +735,46 @@
MHD_UNSIGNED_LONG_LONG mhd_timeout;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
/* initialize PRNG */
srand ((unsigned int) time (NULL));
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL,
- &create_response, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
- MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL,
- MHD_OPTION_END);
+ &create_response, NULL,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ &request_completed_callback, NULL,
+ MHD_OPTION_END);
if (NULL == d)
return 1;
while (1)
+ {
+ expire_sessions ();
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ break; /* fatal internal error */
+ if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
+ {
+ tv.tv_sec = mhd_timeout / 1000;
+ tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
+ tvp = &tv;
+ }
+ else
+ tvp = NULL;
+ if (-1 == select (max + 1, &rs, &ws, &es, tvp))
{
- expire_sessions ();
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- break; /* fatal internal error */
- if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
- {
- tv.tv_sec = mhd_timeout / 1000;
- tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
- tvp = &tv;
- }
- else
- tvp = NULL;
- if (-1 == select (max + 1, &rs, &ws, &es, tvp))
- {
- if (EINTR != errno)
- abort ();
- }
- MHD_run (d);
+ if (EINTR != errno)
+ abort ();
}
+ MHD_run (d);
+ }
MHD_stop_daemon (d);
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/querystring_example.c
^
|
@@ -26,9 +26,10 @@
#include "platform.h"
#include <microhttpd.h>
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Query string for "%s" was "%s"</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Query string for "%s" was "%s"</body></html>"
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -41,16 +42,20 @@
const char *val;
char *me;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
val = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "q");
me = malloc (snprintf (NULL, 0, fmt, "q", val) + 1);
@@ -58,31 +63,41 @@
return MHD_NO;
sprintf (me, fmt, "q", val);
response = MHD_create_response_from_buffer (strlen (me), me,
- MHD_RESPMEM_MUST_FREE);
+ MHD_RESPMEM_MUST_FREE);
if (response == NULL)
- {
- free (me);
- return MHD_NO;
- }
+ {
+ free (me);
+ return MHD_NO;
+ }
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
+
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
+ int port;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- atoi (argv[1]),
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ port = atoi (argv[1]);
+ if ( (port < 0) ||
+ (port > UINT16_MAX) )
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ (uint16_t) port,
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
- if (d == NULL)
+ if (NULL == d)
return 1;
(void) getc (stdin);
MHD_stop_daemon (d);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/refuse_post_example.c
^
|
@@ -24,16 +24,18 @@
#include "platform.h"
#include <microhttpd.h>
-const char *askpage = "<html><body>\n\
+const char *askpage =
+ "<html><body>\n\
Upload a file, please!<br>\n\
<form action=\"/filepost\" method=\"post\" enctype=\"multipart/form-data\">\n\
<input name=\"file\" type=\"file\">\n\
<input type=\"submit\" value=\" Send \"></form>\n\
</body></html>";
-#define BUSYPAGE "<html><head><title>Webserver busy</title></head><body>We are too busy to process POSTs right now.</body></html>"
+#define BUSYPAGE \
+ "<html><head><title>Webserver busy</title></head><body>We are too busy to process POSTs right now.</body></html>"
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -44,49 +46,56 @@
static int aptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if ((0 != strcmp (method, "GET")) && (0 != strcmp (method, "POST")))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- *ptr = &aptr;
+ {
+ *ptr = &aptr;
- /* always to busy for POST requests */
- if (0 == strcmp (method, "POST"))
- {
- response = MHD_create_response_from_buffer (strlen (BUSYPAGE),
- (void *) BUSYPAGE,
- MHD_RESPMEM_PERSISTENT);
- ret =
- MHD_queue_response (connection, MHD_HTTP_SERVICE_UNAVAILABLE,
- response);
- MHD_destroy_response (response);
- return ret;
- }
+ /* always to busy for POST requests */
+ if (0 == strcmp (method, "POST"))
+ {
+ response = MHD_create_response_from_buffer (strlen (BUSYPAGE),
+ (void *) BUSYPAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret =
+ MHD_queue_response (connection, MHD_HTTP_SERVICE_UNAVAILABLE,
+ response);
+ MHD_destroy_response (response);
+ return ret;
}
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (me),
- (void *) me,
- MHD_RESPMEM_PERSISTENT);
+ (void *) me,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
+
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL, &ahc_echo, (void *) askpage,
MHD_OPTION_END);
@@ -97,4 +106,5 @@
return 0;
}
+
/* end of refuse_post_example.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/suspend_resume_epoll.c
^
|
@@ -0,0 +1,218 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2018 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file suspend_resume_epoll.c
+ * @brief example for how to use libmicrohttpd with epoll() and
+ * resume a suspended connection
+ * @author Robert D Kocisko
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <microhttpd.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <limits.h>
+
+#define TIMEOUT_INFINITE -1
+
+struct Request
+{
+ struct MHD_Connection *connection;
+ int timerfd;
+};
+
+
+static int epfd;
+
+static struct epoll_event evt;
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size, void **ptr)
+{
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ struct Request*req;
+ struct itimerspec ts;
+
+ (void) cls;
+ (void) url; /* Unused. Silence compiler warning. */
+ (void) method;
+ (void) version; /* Unused. Silence compiler warning. */
+ (void) upload_data; /* Unused. Silence compiler warning. */
+ (void) upload_data_size; /* Unused. Silence compiler warning. */
+ req = *ptr;
+ if (NULL == req)
+ {
+
+ req = malloc (sizeof(struct Request));
+ if (NULL == req)
+ return MHD_NO;
+ req->connection = connection;
+ req->timerfd = -1;
+ *ptr = req;
+ return MHD_YES;
+ }
+
+ if (-1 != req->timerfd)
+ {
+ /* send response (echo request url) */
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ /* create timer and suspend connection */
+ req->timerfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (-1 == req->timerfd)
+ {
+ printf ("timerfd_create: %s", strerror (errno));
+ return MHD_NO;
+ }
+ evt.events = EPOLLIN;
+ evt.data.ptr = req;
+ if (-1 == epoll_ctl (epfd, EPOLL_CTL_ADD, req->timerfd, &evt))
+ {
+ printf ("epoll_ctl: %s", strerror (errno));
+ return MHD_NO;
+ }
+ ts.it_value.tv_sec = 1;
+ ts.it_value.tv_nsec = 0;
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ if (-1 == timerfd_settime (req->timerfd, 0, &ts, NULL))
+ {
+ printf ("timerfd_settime: %s", strerror (errno));
+ return MHD_NO;
+ }
+ MHD_suspend_connection (connection);
+ return MHD_YES;
+}
+
+
+static void
+connection_done (void *cls,
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
+{
+ struct Request *req = *con_cls;
+
+ (void) cls;
+ (void) connection;
+ (void) toe;
+ if (-1 != req->timerfd)
+ if (0 != close (req->timerfd))
+ abort ();
+ free (req);
+}
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ struct MHD_Daemon *d;
+ const union MHD_DaemonInfo *info;
+ int current_event_count;
+ struct epoll_event events_list[1];
+ struct Request *req;
+ uint64_t timer_expirations;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_USE_EPOLL | MHD_ALLOW_SUSPEND_RESUME,
+ atoi (argv[1]),
+ NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &connection_done, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+
+ info = MHD_get_daemon_info (d, MHD_DAEMON_INFO_EPOLL_FD);
+ if (info == NULL)
+ return 1;
+
+ epfd = epoll_create1 (EPOLL_CLOEXEC);
+ if (-1 == epfd)
+ return 1;
+
+ evt.events = EPOLLIN;
+ evt.data.ptr = NULL;
+ if (-1 == epoll_ctl (epfd, EPOLL_CTL_ADD, info->epoll_fd, &evt))
+ return 1;
+
+ while (1)
+ {
+ int timeout;
+ MHD_UNSIGNED_LONG_LONG to;
+
+ if (MHD_YES !=
+ MHD_get_timeout (d,
+ &to))
+ timeout = TIMEOUT_INFINITE;
+ else
+ timeout = (to < INT_MAX - 1) ? (int) to : (INT_MAX - 1);
+ current_event_count = epoll_wait (epfd, events_list, 1, timeout);
+
+ if (1 == current_event_count)
+ {
+ if (events_list[0].data.ptr)
+ {
+ /* A timer has timed out */
+ req = events_list[0].data.ptr;
+ /* read from the fd so the system knows we heard the notice */
+ if (-1 == read (req->timerfd, &timer_expirations,
+ sizeof(timer_expirations)))
+ {
+ return 1;
+ }
+ /* Now resume the connection */
+ MHD_resume_connection (req->connection);
+ }
+ }
+ else if (0 == current_event_count)
+ {
+ /* no events: continue */
+ }
+ else
+ {
+ /* error */
+ return 1;
+ }
+ if (! MHD_run (d))
+ return 1;
+ }
+
+ return 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/timeout.c
^
|
@@ -1,78 +1,85 @@
-/*
- This file is part of libmicrohttpd
- Copyright (C) 2016, 2017 Christian Grothoff,
- Silvio Clecio (silvioprog), Karlson2k (Evgeny Grin)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-/**
- * @file timeout.c
- * @brief example for how to use libmicrohttpd request timeout
- * @author Christian Grothoff, Silvio Clecio (silvioprog), Karlson2k (Evgeny Grin)
- */
-
-#include <microhttpd.h>
-#include <stdio.h>
-#include <string.h>
-
-#define PORT 8080
-
-static int
-answer_to_connection(void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **con_cls)
-{
- const char *page = "<html><body>Hello timeout!</body></html>";
- struct MHD_Response *response;
- int ret;
-
- response = MHD_create_response_from_buffer (strlen(page),
- (void *) page,
- MHD_RESPMEM_PERSISTENT);
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html");
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response(response);
- return ret;
-}
-
-
-int
-main (int argc,
- char **argv)
-{
- struct MHD_Daemon *daemon;
-
- daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
- PORT,
- NULL, NULL,
- &answer_to_connection, NULL,
- /* 3 seconds */
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 3,
- MHD_OPTION_END);
- if (NULL == daemon)
- return 1;
- getchar();
- MHD_stop_daemon(daemon);
- return 0;
-}
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016, 2017 Christian Grothoff,
+ Silvio Clecio (silvioprog), Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file timeout.c
+ * @brief example for how to use libmicrohttpd request timeout
+ * @author Christian Grothoff, Silvio Clecio (silvioprog), Karlson2k (Evgeny Grin)
+ */
+
+#include <microhttpd.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PORT 8080
+
+static enum MHD_Result
+answer_to_connection (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls)
+{
+ const char *page = "<html><body>Hello timeout!</body></html>";
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) method; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+ (void) con_cls; /* Unused. Silent compiler warning. */
+
+ response = MHD_create_response_from_buffer (strlen (page),
+ (void *) page,
+ MHD_RESPMEM_PERSISTENT);
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html");
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+int
+main (void)
+{
+ struct MHD_Daemon *daemon;
+
+ daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD,
+ PORT,
+ NULL, NULL,
+ &answer_to_connection, NULL,
+ /* 3 seconds */
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 3,
+ MHD_OPTION_END);
+ if (NULL == daemon)
+ return 1;
+ (void) getchar ();
+ MHD_stop_daemon (daemon);
+ return 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/upgrade_example.c
^
|
@@ -32,7 +32,8 @@
#include <microhttpd.h>
#include <pthread.h>
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
/**
@@ -72,23 +73,23 @@
make_blocking (sock);
for (off = 0; off < len; off += ret)
+ {
+ ret = send (sock,
+ &buf[off],
+ len - off,
+ 0);
+ if (0 > ret)
{
- ret = send (sock,
- &buf[off],
- len - off,
- 0);
- if (0 > ret)
- {
- if (EAGAIN == errno)
- {
- ret = 0;
- continue;
- }
- break;
- }
- if (0 == ret)
- break;
+ if (EAGAIN == errno)
+ {
+ ret = 0;
+ continue;
+ }
+ break;
}
+ if (0 == ret)
+ break;
+ }
}
@@ -118,25 +119,25 @@
make_blocking (md->sock);
/* start by sending extra data MHD may have already read, if any */
if (0 != md->extra_in_size)
- {
- send_all (md->sock,
- md->extra_in,
- md->extra_in_size);
- free (md->extra_in);
- }
+ {
+ send_all (md->sock,
+ md->extra_in,
+ md->extra_in_size);
+ free (md->extra_in);
+ }
/* now echo in a loop */
while (1)
- {
- got = recv (md->sock,
- buf,
- sizeof (buf),
- 0);
- if (0 >= got)
- break;
- send_all (md->sock,
+ {
+ got = recv (md->sock,
buf,
- got);
- }
+ sizeof (buf),
+ 0);
+ if (0 >= got)
+ break;
+ send_all (md->sock,
+ buf,
+ got);
+ }
free (md);
MHD_upgrade_action (urh,
MHD_UPGRADE_ACTION_CLOSE);
@@ -202,20 +203,23 @@
{
struct MyData *md;
pthread_t pt;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) connection; /* Unused. Silent compiler warning. */
+ (void) con_cls; /* Unused. Silent compiler warning. */
md = malloc (sizeof (struct MyData));
if (NULL == md)
abort ();
memset (md, 0, sizeof (struct MyData));
if (0 != extra_in_size)
- {
- md->extra_in = malloc (extra_in_size);
- if (NULL == md->extra_in)
- abort ();
- memcpy (md->extra_in,
- extra_in,
- extra_in_size);
- }
+ {
+ md->extra_in = malloc (extra_in_size);
+ if (NULL == md->extra_in)
+ abort ();
+ memcpy (md->extra_in,
+ extra_in,
+ extra_in_size);
+ }
md->extra_in_size = extra_in_size;
md->sock = sock;
md->urh = urh;
@@ -236,7 +240,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -248,16 +252,21 @@
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_for_upgrade (&uh_cb,
NULL);
@@ -280,16 +289,17 @@
struct MHD_Daemon *d;
if (argc != 2)
- {
- printf ("%s PORT\n", argv[0]);
- return 1;
- }
- d = MHD_start_daemon (MHD_ALLOW_UPGRADE | MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ d = MHD_start_daemon (MHD_ALLOW_UPGRADE | MHD_USE_AUTO
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
atoi (argv[1]),
NULL, NULL,
&ahc_echo, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/examples/websocket_threaded_example.c
^
|
@@ -0,0 +1,900 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2020 Christian Grothoff, Silvio Clecio (and other
+ contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file websocket_threaded_example.c
+ * @brief example for how to provide a tiny threaded websocket server
+ * @author Silvio Clecio (silvioprog)
+ */
+
+/* TODO: allow to send large messages. */
+
+#include "platform.h"
+#include <pthread.h>
+#include <microhttpd.h>
+
+#define CHAT_PAGE \
+ "<html>\n" \
+ "<head>\n" \
+ "<title>WebSocket chat</title>\n" \
+ "<script>\n" \
+ "document.addEventListener('DOMContentLoaded', function() {\n" \
+ " const ws = new WebSocket('ws:// ' + window.location.host);\n" /* \
+ " const btn = document.getElementById('send');\n" \
+ " const msg = document.getElementById('msg');\n" \
+ " const log = document.getElementById('log');\n" \
+ " ws.onopen = function() {\n" \
+ " log.value += 'Connected\\n';\n" \
+ " };\n" \
+ " ws.onclose = function() {\n" \
+ " log.value += 'Disconnected\\n';\n" \
+ " };\n" \
+ " ws.onmessage = function(ev) {\n" \
+ " log.value += ev.data + '\\n';\n" \
+ " };\n" \
+ " btn.onclick = function() {\n" \
+ " log.value += '<You>: ' + msg.value + '\\n';\n" \
+ " ws.send(msg.value);\n" \
+ " };\n" \
+ " msg.onkeyup = function(ev) {\n" \
+ " if (ev.keyCode === 13) {\n" \
+ " ev.preventDefault();\n" \
+ " ev.stopPropagation();\n" \
+ " btn.click();\n" \
+ " msg.value = '';\n" \
+ " }\n" \
+ " };\n" \
+ "});\n" \
+ "</script>\n" \
+ "</head>\n" \
+ "<body>\n" \
+ "<input type='text' id='msg' autofocus/>\n" \
+ "<input type='button' id='send' value='Send' /><br /><br />\n" \
+ "<textarea id='log' rows='20' cols='28'></textarea>\n" \
+ "</body>\n" \
+ "</html>" */
+#define BAD_REQUEST_PAGE \
+ "<html>\n" \
+ "<head>\n" \
+ "<title>WebSocket chat</title>\n" \
+ "</head>\n" \
+ "<body>\n" \
+ "Bad Request\n" \
+ "</body>\n" \
+ "</html>\n"
+#define UPGRADE_REQUIRED_PAGE \
+ "<html>\n" \
+ "<head>\n" \
+ "<title>WebSocket chat</title>\n" \
+ "</head>\n" \
+ "<body>\n" \
+ "Upgrade required\n" \
+ "</body>\n" \
+ "</html>\n"
+
+#define WS_SEC_WEBSOCKET_VERSION "13"
+#define WS_UPGRADE_VALUE "websocket"
+#define WS_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+#define WS_GUID_LEN 36
+#define WS_KEY_LEN 24
+#define WS_KEY_GUID_LEN ((WS_KEY_LEN) + (WS_GUID_LEN))
+#define WS_FIN 128
+#define WS_OPCODE_TEXT_FRAME 1
+#define WS_OPCODE_CON_CLOSE_FRAME 8
+
+#define MAX_CLIENTS 10
+
+static MHD_socket CLIENT_SOCKS[MAX_CLIENTS];
+
+static pthread_mutex_t MUTEX = PTHREAD_MUTEX_INITIALIZER;
+
+struct WsData
+{
+ struct MHD_UpgradeResponseHandle *urh;
+ MHD_socket sock;
+};
+
+
+/********** begin SHA-1 **********/
+
+
+#define SHA1HashSize 20
+
+#define SHA1CircularShift(bits, word) \
+ (((word) << (bits)) | ((word) >> (32 - (bits))))
+
+enum SHA1_RESULT
+{
+ SHA1_RESULT_SUCCESS = 0,
+ SHA1_RESULT_NULL = 1,
+ SHA1_RESULT_STATE_ERROR = 2
+};
+
+struct SHA1Context
+{
+ uint32_t intermediate_hash[SHA1HashSize / 4];
+ uint32_t length_low;
+ uint32_t length_high;
+ int_least16_t message_block_index;
+ unsigned char message_block[64];
+ int computed;
+ int corrupted;
+};
+
+static void
+SHA1ProcessMessageBlock (struct SHA1Context *context)
+{
+ const uint32_t K[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
+ int i;
+ uint32_t temp;
+ uint32_t W[80];
+ uint32_t A, B, C, D, E;
+
+ for (i = 0; i < 16; i++)
+ {
+ W[i] = context->message_block[i * 4] << 24;
+ W[i] |= context->message_block[i * 4 + 1] << 16;
+ W[i] |= context->message_block[i * 4 + 2] << 8;
+ W[i] |= context->message_block[i * 4 + 3];
+ }
+ for (i = 16; i < 80; i++)
+ {
+ W[i]
+ = SHA1CircularShift (1, W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]);
+ }
+ A = context->intermediate_hash[0];
+ B = context->intermediate_hash[1];
+ C = context->intermediate_hash[2];
+ D = context->intermediate_hash[3];
+ E = context->intermediate_hash[4];
+ for (i = 0; i < 20; i++)
+ {
+ temp = SHA1CircularShift (5, A) + ((B & C) | ((~B) & D)) + E + W[i]
+ + K[0];
+ E = D;
+ D = C;
+ C = SHA1CircularShift (30, B);
+ B = A;
+ A = temp;
+ }
+ for (i = 20; i < 40; i++)
+ {
+ temp = SHA1CircularShift (5, A) + (B ^ C ^ D) + E + W[i] + K[1];
+ E = D;
+ D = C;
+ C = SHA1CircularShift (30, B);
+ B = A;
+ A = temp;
+ }
+ for (i = 40; i < 60; i++)
+ {
+ temp = SHA1CircularShift (5, A) + ((B & C) | (B & D) | (C & D)) + E
+ + W[i] + K[2];
+ E = D;
+ D = C;
+ C = SHA1CircularShift (30, B);
+ B = A;
+ A = temp;
+ }
+ for (i = 60; i < 80; i++)
+ {
+ temp = SHA1CircularShift (5, A) + (B ^ C ^ D) + E + W[i] + K[3];
+ E = D;
+ D = C;
+ C = SHA1CircularShift (30, B);
+ B = A;
+ A = temp;
+ }
+ context->intermediate_hash[0] += A;
+ context->intermediate_hash[1] += B;
+ context->intermediate_hash[2] += C;
+ context->intermediate_hash[3] += D;
+ context->intermediate_hash[4] += E;
+ context->message_block_index = 0;
+}
+
+
+static void
+SHA1PadMessage (struct SHA1Context *context)
+{
+ if (context->message_block_index > 55)
+ {
+ context->message_block[context->message_block_index++] = 0x80;
+ while (context->message_block_index < 64)
+ {
+ context->message_block[context->message_block_index++] = 0;
+ }
+ SHA1ProcessMessageBlock (context);
+ while (context->message_block_index < 56)
+ {
+ context->message_block[context->message_block_index++] = 0;
+ }
+ }
+ else
+ {
+ context->message_block[context->message_block_index++] = 0x80;
+ while (context->message_block_index < 56)
+ {
+ context->message_block[context->message_block_index++] = 0;
+ }
+ }
+ context->message_block[56] = context->length_high >> 24;
+ context->message_block[57] = context->length_high >> 16;
+ context->message_block[58] = context->length_high >> 8;
+ context->message_block[59] = context->length_high;
+ context->message_block[60] = context->length_low >> 24;
+ context->message_block[61] = context->length_low >> 16;
+ context->message_block[62] = context->length_low >> 8;
+ context->message_block[63] = context->length_low;
+ SHA1ProcessMessageBlock (context);
+}
+
+
+static enum SHA1_RESULT
+SHA1Reset (struct SHA1Context *context)
+{
+ if (! context)
+ {
+ return SHA1_RESULT_NULL;
+ }
+ context->length_low = 0;
+ context->length_high = 0;
+ context->message_block_index = 0;
+ context->intermediate_hash[0] = 0x67452301;
+ context->intermediate_hash[1] = 0xEFCDAB89;
+ context->intermediate_hash[2] = 0x98BADCFE;
+ context->intermediate_hash[3] = 0x10325476;
+ context->intermediate_hash[4] = 0xC3D2E1F0;
+ context->computed = 0;
+ context->corrupted = 0;
+ return SHA1_RESULT_SUCCESS;
+}
+
+
+static enum SHA1_RESULT
+SHA1Result (struct SHA1Context *context, unsigned char
+ Message_Digest[SHA1HashSize])
+{
+ int i;
+
+ if (! context || ! Message_Digest)
+ {
+ return SHA1_RESULT_NULL;
+ }
+ if (context->corrupted)
+ {
+ return context->corrupted;
+ }
+ if (! context->computed)
+ {
+ SHA1PadMessage (context);
+ for (i = 0; i < 64; ++i)
+ {
+ context->message_block[i] = 0;
+ }
+ context->length_low = 0;
+ context->length_high = 0;
+ context->computed = 1;
+ }
+ for (i = 0; i < SHA1HashSize; ++i)
+ {
+ Message_Digest[i]
+ = context->intermediate_hash[i >> 2] >> 8 * (3 - (i & 0x03));
+ }
+ return SHA1_RESULT_SUCCESS;
+}
+
+
+static enum SHA1_RESULT
+SHA1Input (struct SHA1Context *context, const unsigned char *message_array,
+ unsigned length)
+{
+ if (! length)
+ {
+ return SHA1_RESULT_SUCCESS;
+ }
+ if (! context || ! message_array)
+ {
+ return SHA1_RESULT_NULL;
+ }
+ if (context->computed)
+ {
+ context->corrupted = SHA1_RESULT_STATE_ERROR;
+ return SHA1_RESULT_STATE_ERROR;
+ }
+ if (context->corrupted)
+ {
+ return context->corrupted;
+ }
+ while (length-- && ! context->corrupted)
+ {
+ context->message_block[context->message_block_index++]
+ = (*message_array & 0xFF);
+ context->length_low += 8;
+ if (context->length_low == 0)
+ {
+ context->length_high++;
+ if (context->length_high == 0)
+ {
+ context->corrupted = 1;
+ }
+ }
+ if (context->message_block_index == 64)
+ {
+ SHA1ProcessMessageBlock (context);
+ }
+ message_array++;
+ }
+ return SHA1_RESULT_SUCCESS;
+}
+
+
+/********** end SHA-1 **********/
+
+
+/********** begin Base64 **********/
+
+
+ssize_t
+BASE64Encode (const void *in, size_t len, char **output)
+{
+#define FILLCHAR '='
+ const char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ const char *data = in;
+ char *opt;
+ ssize_t ret;
+ size_t i;
+ char c;
+ ret = 0;
+
+ opt = malloc (2 + (len * 4 / 3) + 8);
+ if (NULL == opt)
+ {
+ return -1;
+ }
+ for (i = 0; i < len; ++i)
+ {
+ c = (data[i] >> 2) & 0x3F;
+ opt[ret++] = cvt[(int) c];
+ c = (data[i] << 4) & 0x3F;
+ if (++i < len)
+ {
+ c |= (data[i] >> 4) & 0x0F;
+ }
+ opt[ret++] = cvt[(int) c];
+ if (i < len)
+ {
+ c = (data[i] << 2) & 0x3F;
+ if (++i < len)
+ {
+ c |= (data[i] >> 6) & 0x03;
+ }
+ opt[ret++] = cvt[(int) c];
+ }
+ else
+ {
+ ++i;
+ opt[ret++] = FILLCHAR;
+ }
+ if (i < len)
+ {
+ c = data[i] & 0x3F;
+ opt[ret++] = cvt[(int) c];
+ }
+ else
+ {
+ opt[ret++] = FILLCHAR;
+ }
+ }
+ *output = opt;
+ return ret;
+}
+
+
+/********** end Base64 **********/
+
+
+static enum MHD_Result
+is_websocket_request (struct MHD_Connection *con, const char *upg_header,
+ const char *con_header)
+{
+
+ (void) con; /* Unused. Silent compiler warning. */
+
+ return (upg_header != NULL) && (con_header != NULL)
+ && (0 == strcmp (upg_header, WS_UPGRADE_VALUE))
+ && (NULL != strstr (con_header, "Upgrade"))
+ ? MHD_YES
+ : MHD_NO;
+}
+
+
+static enum MHD_Result
+send_chat_page (struct MHD_Connection *con)
+{
+ struct MHD_Response *res;
+ enum MHD_Result ret;
+
+ res = MHD_create_response_from_buffer (strlen (CHAT_PAGE), (void *) CHAT_PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (con, MHD_HTTP_OK, res);
+ MHD_destroy_response (res);
+ return ret;
+}
+
+
+static enum MHD_Result
+send_bad_request (struct MHD_Connection *con)
+{
+ struct MHD_Response *res;
+ enum MHD_Result ret;
+
+ res = MHD_create_response_from_buffer (strlen (BAD_REQUEST_PAGE),
+ (void *) BAD_REQUEST_PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (con, MHD_HTTP_BAD_REQUEST, res);
+ MHD_destroy_response (res);
+ return ret;
+}
+
+
+static enum MHD_Result
+send_upgrade_required (struct MHD_Connection *con)
+{
+ struct MHD_Response *res;
+ enum MHD_Result ret;
+
+ res = MHD_create_response_from_buffer (strlen (UPGRADE_REQUIRED_PAGE),
+ (void *) UPGRADE_REQUIRED_PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ MHD_add_response_header (res, MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION,
+ WS_SEC_WEBSOCKET_VERSION);
+ ret = MHD_queue_response (con, MHD_HTTP_UPGRADE_REQUIRED, res);
+ MHD_destroy_response (res);
+ return ret;
+}
+
+
+static enum MHD_Result
+ws_get_accept_value (const char *key, char **val)
+{
+ struct SHA1Context ctx;
+ unsigned char hash[SHA1HashSize];
+ char *str;
+ ssize_t len;
+
+ if ( (NULL == key) || (WS_KEY_LEN != strlen (key)))
+ {
+ return MHD_NO;
+ }
+ str = malloc (WS_KEY_LEN + WS_GUID_LEN + 1);
+ if (NULL == str)
+ {
+ return MHD_NO;
+ }
+ strncpy (str, key, (WS_KEY_LEN + 1));
+ strncpy (str + WS_KEY_LEN, WS_GUID, WS_GUID_LEN + 1);
+ SHA1Reset (&ctx);
+ SHA1Input (&ctx, (const unsigned char *) str, WS_KEY_GUID_LEN);
+ SHA1Result (&ctx, hash);
+ free (str);
+ len = BASE64Encode (hash, SHA1HashSize, val);
+ if (-1 == len)
+ {
+ return MHD_NO;
+ }
+ (*val)[len] = '\0';
+ return MHD_YES;
+}
+
+
+static void
+make_blocking (MHD_socket fd)
+{
+#if defined(MHD_POSIX_SOCKETS)
+ int flags;
+
+ flags = fcntl (fd, F_GETFL);
+ if (-1 == flags)
+ return;
+ if ((flags & ~O_NONBLOCK) != flags)
+ if (-1 == fcntl (fd, F_SETFL, flags & ~O_NONBLOCK))
+ abort ();
+#elif defined(MHD_WINSOCK_SOCKETS)
+ unsigned long flags = 1;
+
+ ioctlsocket (fd, FIONBIO, &flags);
+#endif /* MHD_WINSOCK_SOCKETS */
+}
+
+
+static size_t
+send_all (MHD_socket sock, const unsigned char *buf, size_t len)
+{
+ ssize_t ret;
+ size_t off;
+
+ for (off = 0; off < len; off += ret)
+ {
+ ret = send (sock, (const void*) &buf[off], len - off, 0);
+ if (0 > ret)
+ {
+ if (EAGAIN == errno)
+ {
+ ret = 0;
+ continue;
+ }
+ break;
+ }
+ if (0 == ret)
+ {
+ break;
+ }
+ }
+ return off;
+}
+
+
+static int
+ws_send_frame (MHD_socket sock, const char *msg, size_t length)
+{
+ unsigned char *response;
+ unsigned char frame[10];
+ unsigned char idx_first_rdata;
+ int idx_response;
+ int output;
+ MHD_socket isock;
+ size_t i;
+
+ frame[0] = (WS_FIN | WS_OPCODE_TEXT_FRAME);
+ if (length <= 125)
+ {
+ frame[1] = length & 0x7F;
+ idx_first_rdata = 2;
+ }
+ else if ((length >= 126) && (length <= 0xFFFF))
+ {
+ frame[1] = 126;
+ frame[2] = (length >> 8) & 0xFF;
+ frame[3] = length & 0xFF;
+ idx_first_rdata = 4;
+ }
+ else
+ {
+ frame[1] = 127;
+ frame[2] = (unsigned char) ((length >> 56) & 0xFF);
+ frame[3] = (unsigned char) ((length >> 48) & 0xFF);
+ frame[4] = (unsigned char) ((length >> 40) & 0xFF);
+ frame[5] = (unsigned char) ((length >> 32) & 0xFF);
+ frame[6] = (unsigned char) ((length >> 24) & 0xFF);
+ frame[7] = (unsigned char) ((length >> 16) & 0xFF);
+ frame[8] = (unsigned char) ((length >> 8) & 0xFF);
+ frame[9] = (unsigned char) (length & 0xFF);
+ idx_first_rdata = 10;
+ }
+ idx_response = 0;
+ response = malloc (idx_first_rdata + length + 1);
+ if (NULL == response)
+ {
+ return -1;
+ }
+ for (i = 0; i < idx_first_rdata; i++)
+ {
+ response[i] = frame[i];
+ idx_response++;
+ }
+ for (i = 0; i < length; i++)
+ {
+ response[idx_response] = msg[i];
+ idx_response++;
+ }
+ response[idx_response] = '\0';
+ output = 0;
+ pthread_mutex_lock (&MUTEX);
+ for (i = 0; i < MAX_CLIENTS; i++)
+ {
+ isock = CLIENT_SOCKS[i];
+ if ((isock != MHD_INVALID_SOCKET) && (isock != sock))
+ {
+ output += send_all (isock, response, idx_response);
+ }
+ }
+ pthread_mutex_unlock (&MUTEX);
+ free (response);
+ return output;
+}
+
+
+static unsigned char *
+ws_receive_frame (unsigned char *frame, ssize_t *length, int *type)
+{
+ unsigned char masks[4];
+ unsigned char mask;
+ unsigned char *msg;
+ unsigned char flength;
+ unsigned char idx_first_mask;
+ unsigned char idx_first_data;
+ ssize_t data_length;
+ int i;
+ int j;
+
+ msg = NULL;
+ if (frame[0] == (WS_FIN | WS_OPCODE_TEXT_FRAME))
+ {
+ *type = WS_OPCODE_TEXT_FRAME;
+ idx_first_mask = 2;
+ mask = frame[1];
+ flength = mask & 0x7F;
+ if (flength == 126)
+ {
+ idx_first_mask = 4;
+ }
+ else if (flength == 127)
+ {
+ idx_first_mask = 10;
+ }
+ idx_first_data = idx_first_mask + 4;
+ data_length = *length - idx_first_data;
+ masks[0] = frame[idx_first_mask + 0];
+ masks[1] = frame[idx_first_mask + 1];
+ masks[2] = frame[idx_first_mask + 2];
+ masks[3] = frame[idx_first_mask + 3];
+ msg = malloc (data_length + 1);
+ if (NULL != msg)
+ {
+ for (i = idx_first_data, j = 0; i < *length; i++, j++)
+ {
+ msg[j] = frame[i] ^ masks[j % 4];
+ }
+ *length = data_length;
+ msg[j] = '\0';
+ }
+ }
+ else if (frame[0] == (WS_FIN | WS_OPCODE_CON_CLOSE_FRAME))
+ {
+ *type = WS_OPCODE_CON_CLOSE_FRAME;
+ }
+ else
+ {
+ *type = frame[0] & 0x0F;
+ }
+ return msg;
+}
+
+
+static void *
+run_usock (void *cls)
+{
+ struct WsData *ws = cls;
+ struct MHD_UpgradeResponseHandle *urh = ws->urh;
+ unsigned char buf[2048];
+ unsigned char *msg;
+ char client[20];
+ char *text;
+ ssize_t got;
+ size_t size;
+ int type;
+ int sent;
+ int i;
+
+ make_blocking (ws->sock);
+ while (1)
+ {
+ got = recv (ws->sock, (void*) buf, sizeof (buf), 0);
+ if (0 >= got)
+ {
+ break;
+ }
+ msg = ws_receive_frame (buf, &got, &type);
+ if (NULL == msg)
+ {
+ break;
+ }
+ if (type == WS_OPCODE_TEXT_FRAME)
+ {
+ size = sprintf (client, "User#%d: ", (int) ws->sock);
+ size += got;
+ text = malloc (size);
+ if (NULL != text)
+ {
+ sprintf (text, "%s%s", client, msg);
+ sent = ws_send_frame (ws->sock, text, size);
+ free (text);
+ }
+ else
+ {
+ sent = -1;
+ }
+ free (msg);
+ if (-1 == sent)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (type == WS_OPCODE_CON_CLOSE_FRAME)
+ {
+ free (msg);
+ break;
+ }
+ }
+ }
+ pthread_mutex_lock (&MUTEX);
+ for (i = 0; i < MAX_CLIENTS; i++)
+ {
+ if (CLIENT_SOCKS[i] == ws->sock)
+ {
+ CLIENT_SOCKS[i] = MHD_INVALID_SOCKET;
+ break;
+ }
+ }
+ pthread_mutex_unlock (&MUTEX);
+ free (ws);
+ MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE);
+ return NULL;
+}
+
+
+static void
+uh_cb (void *cls, struct MHD_Connection *con, void *con_cls,
+ const char *extra_in, size_t extra_in_size, MHD_socket sock,
+ struct MHD_UpgradeResponseHandle *urh)
+{
+ struct WsData *ws;
+ pthread_t pt;
+ int sock_overflow;
+ int i;
+
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) con; /* Unused. Silent compiler warning. */
+ (void) con_cls; /* Unused. Silent compiler warning. */
+ (void) extra_in; /* Unused. Silent compiler warning. */
+ (void) extra_in_size; /* Unused. Silent compiler warning. */
+
+ ws = malloc (sizeof (struct WsData));
+ if (NULL == ws)
+ abort ();
+ memset (ws, 0, sizeof (struct WsData));
+ ws->sock = sock;
+ ws->urh = urh;
+ sock_overflow = MHD_YES;
+ pthread_mutex_lock (&MUTEX);
+ for (i = 0; i < MAX_CLIENTS; i++)
+ {
+ if (MHD_INVALID_SOCKET == CLIENT_SOCKS[i])
+ {
+ CLIENT_SOCKS[i] = ws->sock;
+ sock_overflow = MHD_NO;
+ break;
+ }
+ }
+ pthread_mutex_unlock (&MUTEX);
+ if (sock_overflow)
+ {
+ free (ws);
+ MHD_upgrade_action (urh, MHD_UPGRADE_ACTION_CLOSE);
+ return;
+ }
+ if (0 != pthread_create (&pt, NULL, &run_usock, ws))
+ abort ();
+ /* Note that by detaching like this we make it impossible to ensure
+ a clean shutdown, as the we stop the daemon even if a worker thread
+ is still running. Alas, this is a simple example... */
+ pthread_detach (pt);
+}
+
+
+static enum MHD_Result
+ahc_cb (void *cls, struct MHD_Connection *con, const char *url,
+ const char *method, const char *version, const char *upload_data,
+ size_t *upload_data_size, void **ptr)
+{
+ struct MHD_Response *res;
+ const char *upg_header;
+ const char *con_header;
+ const char *ws_version_header;
+ const char *ws_key_header;
+ char *ws_ac_value;
+ enum MHD_Result ret;
+ size_t key_size;
+
+ (void) cls; /* Unused. Silent compiler warning. */
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (NULL == *ptr)
+ {
+ *ptr = (void *) 1;
+ return MHD_YES;
+ }
+ *ptr = NULL;
+ upg_header = MHD_lookup_connection_value (con, MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_UPGRADE);
+ con_header = MHD_lookup_connection_value (con, MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONNECTION);
+ if (MHD_NO == is_websocket_request (con, upg_header, con_header))
+ {
+ return send_chat_page (con);
+ }
+ if ((0 != strcmp (method, MHD_HTTP_METHOD_GET))
+ || (0 != strcmp (version, MHD_HTTP_VERSION_1_1)))
+ {
+ return send_bad_request (con);
+ }
+ ws_version_header = MHD_lookup_connection_value (
+ con, MHD_HEADER_KIND, MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION);
+ if ((NULL == ws_version_header)
+ || (0 != strcmp (ws_version_header, WS_SEC_WEBSOCKET_VERSION)))
+ {
+ return send_upgrade_required (con);
+ }
+ ret = MHD_lookup_connection_value_n (
+ con, MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY,
+ strlen (MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY),
+ &ws_key_header, &key_size);
+ if ((MHD_NO == ret) || (key_size != WS_KEY_LEN))
+ {
+ return send_bad_request (con);
+ }
+ ret = ws_get_accept_value (ws_key_header, &ws_ac_value);
+ if (MHD_NO == ret)
+ {
+ return ret;
+ }
+ res = MHD_create_response_for_upgrade (&uh_cb, NULL);
+ MHD_add_response_header (res, MHD_HTTP_HEADER_UPGRADE, WS_UPGRADE_VALUE);
+ MHD_add_response_header (res, MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT,
+ ws_ac_value);
+ free (ws_ac_value);
+ ret = MHD_queue_response (con, MHD_HTTP_SWITCHING_PROTOCOLS, res);
+ MHD_destroy_response (res);
+ return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ struct MHD_Daemon *d;
+ uint16_t port;
+ size_t i;
+
+ if (argc != 2)
+ {
+ printf ("%s PORT\n", argv[0]);
+ return 1;
+ }
+ port = atoi (argv[1]);
+ d = MHD_start_daemon (MHD_ALLOW_UPGRADE | MHD_USE_AUTO_INTERNAL_THREAD
+ | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_cb, &port, MHD_OPTION_END);
+ if (NULL == d)
+ return 1;
+ for (i = 0; i < sizeof(CLIENT_SOCKS) / sizeof(CLIENT_SOCKS[0]); ++i)
+ CLIENT_SOCKS[i] = MHD_INVALID_SOCKET;
+ (void) getc (stdin);
+ MHD_stop_daemon (d);
+ return 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/check_record_pending.c
^
|
@@ -0,0 +1,6 @@
+enum MHD_Bool
+(*check_record_pending)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+see:
+gnutls_record_check_pending (connection->tls_session)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/handshake.c
^
|
@@ -0,0 +1,14 @@
+enum MHD_Bool
+(*handshake)(void *cls,
+ struct MHD_TLS_ConnectionState *cs) :
+
+
+ if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+{ /* HTTPS connection. */
+ if (MHD_TLS_CONN_CONNECTED > connection->tls_state)
+ {
+ if (! MHD_run_tls_handshake_ (connection))
+ return MHD_FALSE;
+ }
+}
+return MHD_TRUE;
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/idle_ready.c
^
|
@@ -0,0 +1,12 @@
+enum MHD_Bool
+(*idle_ready)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+
+if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+{ /* HTTPS connection. */
+ if ((MHD_TLS_CONN_INIT <= connection->tls_state) &&
+ (MHD_TLS_CONN_CONNECTED > connection->tls_state))
+ return false;
+}
+return true;
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/init.c
^
|
@@ -0,0 +1,163 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file gnutls/init.c
+ * @brief gnutls-specific initialization routines
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "init.h"
+
+
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
+#if defined(MHD_USE_POSIX_THREADS)
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#elif defined(MHD_W32_MUTEX_)
+
+
+static int
+gcry_w32_mutex_init (void **ppmtx)
+{
+ *ppmtx = malloc (sizeof (MHD_mutex_));
+
+ if (NULL == *ppmtx)
+ return ENOMEM;
+ if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
+ {
+ free (*ppmtx);
+ *ppmtx = NULL;
+ return EPERM;
+ }
+ return 0;
+}
+
+
+static int
+gcry_w32_mutex_destroy (void **ppmtx)
+{
+ int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
+ free (*ppmtx);
+ return res;
+}
+
+
+static int
+gcry_w32_mutex_lock (void **ppmtx)
+{
+ return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
+}
+
+
+static int
+gcry_w32_mutex_unlock (void **ppmtx)
+{
+ return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
+}
+
+
+static struct gcry_thread_cbs gcry_threads_w32 = {
+ (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
+ NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
+ gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+#endif /* defined(MHD_W32_MUTEX_) */
+#endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+
+
+#ifndef _AUTOINIT_FUNCS_ARE_SUPPORTED
+
+/**
+ * Track global initialisation
+ */
+volatile int global_init_count = 0;
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+/**
+ * Global initialisation mutex
+ */
+MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+
+#endif
+
+
+/**
+ * Check whether global initialisation was performed
+ * and call initialiser if necessary.
+ */
+void
+MHD_TLS_check_global_init_ (void)
+{
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_lock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+ if (0 == global_init_count++)
+ MHD_init ();
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_unlock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+}
+
+
+/**
+ * Initialize do setup work.
+ */
+void
+MHD_TLS_init (void)
+{
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ WSADATA wsd;
+#endif /* _WIN32 && ! __CYGWIN__ */
+
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#if GCRYPT_VERSION_NUMBER < 0x010600
+#if defined(MHD_USE_POSIX_THREADS)
+ if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
+ &gcry_threads_pthread))
+ MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
+#elif defined(MHD_W32_MUTEX_)
+ if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
+ &gcry_threads_w32))
+ MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
+#endif /* defined(MHD_W32_MUTEX_) */
+ gcry_check_version (NULL);
+#else
+ if (NULL == gcry_check_version ("1.6.0"))
+ MHD_PANIC (_ (
+ "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
+#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ gnutls_global_init ();
+}
+
+
+void
+MHD_TLS_fini (void)
+{
+ gnutls_global_deinit ();
+}
+
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+_SET_INIT_AND_DEINIT_FUNCS (MHD_TLS_init, MHD_TLS_fini);
+#endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/init.h
^
|
@@ -0,0 +1,46 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file gnutls/init.h
+ * @brief functions to initialize library
+ * @author Christian Grothoff
+ */
+#ifndef INIT_H
+#define INIT_H
+
+#include "internal.h"
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+/**
+ * Do nothing - global initialisation is
+ * performed by library constructor.
+ */
+#define MHD_TLS_check_global_init_() (void) 0
+#else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+/**
+ * Check whether global initialisation was performed
+ * and call initialiser if necessary.
+ */
+void
+MHD_TLS_check_global_init_ (void);
+
+#endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+
+
+#endif /* INIT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/recv.c
^
|
@@ -0,0 +1,5 @@
+recv :
+
+res = gnutls_record_recv (connection->tls_session,
+ &urh->in_buffer[urh->in_buffer_used],
+ buf_size);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/send.c
^
|
@@ -0,0 +1,11 @@
+ssize_t
+(*send)(void *cls,
+ struct MHD_TLS_ConnectionState *cs,
+ const void *buf,
+ size_t buf_size);
+
+
+see:
+res = gnutls_record_send (connection->tls_session,
+ urh->out_buffer,
+ data_size);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/setup_connection.c
^
|
@@ -0,0 +1,58 @@
+setup_connection ()
+{
+ connection->tls_state = MHD_TLS_CONN_INIT;
+ MHD_set_https_callbacks (connection);
+ gnutls_init (&connection->tls_session,
+ GNUTLS_SERVER
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
+ | GNUTLS_NO_SIGNAL
+#endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
+#if GNUTLS_VERSION_MAJOR >= 3
+ | GNUTLS_NONBLOCK
+#endif /* GNUTLS_VERSION_MAJOR >= 3*/
+ );
+ gnutls_priority_set (connection->tls_session,
+ daemon->priority_cache);
+ switch (daemon->cred_type)
+ {
+ /* set needed credentials for certificate authentication. */
+ case GNUTLS_CRD_CERTIFICATE:
+ gnutls_credentials_set (connection->tls_session,
+ GNUTLS_CRD_CERTIFICATE,
+ daemon->x509_cred);
+ break;
+ default:
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ (
+ "Failed to setup TLS credentials: unknown credential type %d.\n"),
+ daemon->cred_type);
+#endif
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection);
+ MHD_PANIC (_ ("Unknown credential type.\n"));
+#if EINVAL
+ errno = EINVAL;
+#endif
+ return MHD_NO;
+ }
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
+ gnutls_transport_set_int (connection->tls_session, (int) (client_socket));
+#else /* GnuTLS before 3.1.9 or Win x64 */
+ gnutls_transport_set_ptr (connection->tls_session,
+ (gnutls_transport_ptr_t) (intptr_t) (client_socket));
+#endif /* GnuTLS before 3.1.9 */
+#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
+ gnutls_transport_set_push_function (connection->tls_session,
+ MHD_tls_push_func_);
+#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
+ if (daemon->https_mem_trust)
+ gnutls_certificate_server_set_request (connection->tls_session,
+ GNUTLS_CERT_REQUEST);
+#else /* ! HTTPS_SUPPORT */
+ return NULL;
+
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/shutdown_connection.c
^
|
@@ -0,0 +1,5 @@
+enum MHD_Bool
+(*shutdown_connection)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+see: MHD_tls_connection_shutdown ()
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/strerror.c
^
|
@@ -0,0 +1,6 @@
+const char *
+(*strerror)(void *cls,
+ int ec);
+
+see:
+gnutls_strerror (ec));
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/teardown_connection.c
^
|
@@ -0,0 +1,4 @@
+teardown_connection ()
+{
+ gnutls_deinit (connection->tls_session);
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/gnutls/update_event_loop_info.c
^
|
@@ -0,0 +1,20 @@
+enum MHD_Bool
+(*update_event_loop_info)(void *cls,
+ struct MHD_TLS_ConnectionState *cs,
+ enum MHD_RequestEventLoopInfo *eli);
+
+
+switch (connection->tls_state)
+{
+case MHD_TLS_CONN_INIT:
+ *eli = MHD_EVENT_LOOP_INFO_READ;
+ return true;
+case MHD_TLS_CONN_HANDSHAKING:
+ if (0 == gnutls_record_get_direction (connection->tls_session))
+ *eli = MHD_EVENT_LOOP_INFO_READ;
+ else
+ *eli = MHD_EVENT_LOOP_INFO_WRITE;
+ return true;
+default:
+ return false;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/Makefile.am
^
|
@@ -2,5 +2,6 @@
SUBDIRS = .
include_HEADERS = microhttpd.h
+noinst_HEADERS = microhttpd2.h microhttpd_tls.h
EXTRA_DIST = platform.h autoinit_funcs.h mhd_options.h
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/autoinit_funcs.h
^
|
@@ -20,7 +20,7 @@
/*
General usage is simple: include this header, declare or define two
functions with zero parameters (void) and any return type: one for
- initialization and one for deinitialization, add
+ initialization and one for deinitialization, add
_SET_INIT_AND_DEINIT_FUNCS(FuncInitName, FuncDeInitName) to the code
and functions will be automatically called during application startup
and shutdown.
@@ -64,15 +64,15 @@
#define AUTOINIT_FUNCS_INCLUDED 1
/**
-* Current version of the header.
+* Current version of the header in packed BCD form.
* 0x01093001 = 1.9.30-1.
*/
-#define AUTOINIT_FUNCS_VERSION 0x01000100
+#define AUTOINIT_FUNCS_VERSION 0x01000200
-#if defined(__GNUC__)
- /* if possible - check for supported attribute */
+#if defined(__GNUC__) || defined(__clang__)
+/* if possible - check for supported attribute */
#ifdef __has_attribute
-#if !__has_attribute(constructor) || !__has_attribute(destructor)
+#if ! __has_attribute (constructor) || ! __has_attribute (destructor)
#define _GNUC_ATTR_CONSTR_NOT_SUPPORTED 1
#endif /* !__has_attribute(constructor) || !__has_attribute(destructor) */
#endif /* __has_attribute */
@@ -80,20 +80,21 @@
/* "_attribute__ ((constructor))" is supported by GCC, clang and
Sun/Oracle compiler starting from version 12.1. */
-#if (defined(__GNUC__) && !defined(_GNUC_ATTR_CONSTR_NOT_SUPPORTED)) || \
- (defined(__SUNPRO_C) && __SUNPRO_C+0 >= 0x5100)
+#if ((defined(__GNUC__) || defined(__clang__)) && \
+ ! defined(_GNUC_ATTR_CONSTR_NOT_SUPPORTED)) || \
+ (defined(__SUNPRO_C) && __SUNPRO_C + 0 >= 0x5100)
#define GNUC_SET_INIT_AND_DEINIT(FI,FD) \
- void __attribute__ ((constructor)) _GNUC_init_helper_##FI(void) \
- { (void)(FI)(); } \
- void __attribute__ ((destructor)) _GNUC_deinit_helper_##FD(void) \
- { (void)(FD)(); } \
- struct _GNUC_dummy_str_##FI{int i;}
+ void __attribute__ ((constructor)) _GNUC_init_helper_ ## FI (void) \
+ { (void) (FI) (); } \
+ void __attribute__ ((destructor)) _GNUC_deinit_helper_ ## FD (void) \
+ { (void) (FD) (); } \
+ struct _GNUC_dummy_str_ ## FI {int i;}
-#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) GNUC_SET_INIT_AND_DEINIT(FI,FD)
+#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) GNUC_SET_INIT_AND_DEINIT (FI,FD)
#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
-#elif defined (_MSC_FULL_VER) && _MSC_VER+0 >= 1600
+#elif defined (_MSC_FULL_VER) && _MSC_VER + 0 >= 1600
/* Make sure that your project/sources define:
_LIB if building a static library (_LIB is ignored if _CONSOLE is defined);
@@ -107,9 +108,9 @@
/* Stringify macros */
#define _INSTRMACRO(a) #a
-#define _STRMACRO(a) _INSTRMACRO(a)
+#define _STRMACRO(a) _INSTRMACRO (a)
-#if !defined(_USRDLL) || defined(AUTOINIT_FUNCS_DECLARE_STATIC_REG)
+#if ! defined(_USRDLL) || defined(AUTOINIT_FUNCS_DECLARE_STATIC_REG)
/* required for atexit() */
#include <stdlib.h>
@@ -128,15 +129,16 @@
#define W32_VARDECORPEFIXSTR ""
#elif defined(_M_IX86) || defined(_X86_)
#define W32_VARDECORPREFIX _
-#define W32_DECORVARNAME(v) _##v
+#define W32_DECORVARNAME(v) _ ## v
#define W32_VARDECORPEFIXSTR "_"
#else
#error Do not know how to decorate symbols for this architecture
#endif
/* Internal variable prefix (can be any) */
-#define W32_INITHELPERVARNAME(f) _initHelperDummy_##f
-#define W32_INITHELPERVARNAMEDECORSTR(f) W32_VARDECORPEFIXSTR _STRMACRO(W32_INITHELPERVARNAME(f))
+#define W32_INITHELPERVARNAME(f) _initHelperDummy_ ## f
+#define W32_INITHELPERVARNAMEDECORSTR(f) W32_VARDECORPEFIXSTR _STRMACRO ( \
+ W32_INITHELPERVARNAME (f))
/* Declare section (segment), put variable pointing to init function to chosen segment,
force linker to include variable to avoid omitting by optimizer */
@@ -145,9 +147,10 @@
/* Return value is ignored for C++ initializers */
/* For C initializers: startup process is aborted if initializer return non-zero */
#define W32_FPTR_IN_SEG(S,F) \
- __pragma(section(S,long,read)) \
- __pragma(comment(linker, "/INCLUDE:" W32_INITHELPERVARNAMEDECORSTR(F))) \
- W32_INITVARDECL __declspec(allocate(S)) int(__cdecl *W32_INITHELPERVARNAME(F))(void) = &F
+ __pragma (section (S,long,read)) \
+ __pragma (comment (linker, "/INCLUDE:" W32_INITHELPERVARNAMEDECORSTR (F))) \
+ W32_INITVARDECL __declspec(allocate (S))int (__cdecl * W32_INITHELPERVARNAME ( \
+ F))(void) = &F
/* Section (segment) names for pointers to initializers */
#define W32_SEG_INIT_C_USER ".CRT$XCU"
@@ -161,10 +164,10 @@
during application startup */
/* "lib" initializers are called before "user" initializers */
/* "C" initializers are called before "C++" initializers */
-#define W32_REG_INIT_C_USER(F) W32_FPTR_IN_SEG(W32_SEG_INIT_C_USER,F)
-#define W32_REG_INIT_C_LIB(F) W32_FPTR_IN_SEG(W32_SEG_INIT_C_LIB,F)
-#define W32_REG_INIT_CXX_USER(F) W32_FPTR_IN_SEG(W32_SEG_INIT_CXX_USER,F)
-#define W32_REG_INIT_CXX_LIB(F) W32_FPTR_IN_SEG(W32_SEG_INIT_CXX_LIB,F)
+#define W32_REG_INIT_C_USER(F) W32_FPTR_IN_SEG (W32_SEG_INIT_C_USER,F)
+#define W32_REG_INIT_C_LIB(F) W32_FPTR_IN_SEG (W32_SEG_INIT_C_LIB,F)
+#define W32_REG_INIT_CXX_USER(F) W32_FPTR_IN_SEG (W32_SEG_INIT_CXX_USER,F)
+#define W32_REG_INIT_CXX_LIB(F) W32_FPTR_IN_SEG (W32_SEG_INIT_CXX_LIB,F)
/* Choose main register macro based on language and program type */
/* Assuming that _LIB or _USRDLL is defined for static or DLL-library */
@@ -174,16 +177,18 @@
/* Define AUTOINIT_FUNCS_FORCE_USER_LVL_INIT to register initializers
at user level even if building library */
#ifdef __cplusplus
-#if ((defined(_LIB) && !defined(_CONSOLE)) || defined(_USRDLL)) && !defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
-#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_LIB(F)
+#if ((defined(_LIB) && ! defined(_CONSOLE)) || defined(_USRDLL)) && \
+ ! defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
+#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_LIB (F)
#else /* ! _LIB && ! _DLL */
-#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_USER(F)
+#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_USER (F)
#endif /* ! _LIB && ! _DLL */
#else /* !__cplusplus*/
-#if ((defined(_LIB) && !defined(_CONSOLE)) || defined(_USRDLL)) && !defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
-#define W32_REGISTER_INIT(F) W32_REG_INIT_C_LIB(F)
+#if ((defined(_LIB) && ! defined(_CONSOLE)) || defined(_USRDLL)) && \
+ ! defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
+#define W32_REGISTER_INIT(F) W32_REG_INIT_C_LIB (F)
#else /* ! _LIB && ! _DLL */
-#define W32_REGISTER_INIT(F) W32_REG_INIT_C_USER(F)
+#define W32_REGISTER_INIT(F) W32_REG_INIT_C_USER (F)
#endif /* ! _LIB && ! _DLL */
#endif /* !__cplusplus*/
@@ -197,36 +202,36 @@
#endif /* _USRDLL */
-#if !defined(_USRDLL) || defined(AUTOINIT_FUNCS_FORCE_STATIC_REG)
+#if ! defined(_USRDLL) || defined(AUTOINIT_FUNCS_FORCE_STATIC_REG)
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
- void __cdecl _W32_deinit_helper_##FD(void) \
- { (void)(FD)(); } \
- int __cdecl _W32_init_helper_##FI(void) \
- { (void)(FI)(); atexit(_W32_deinit_helper_##FD); return 0; } \
- W32_REGISTER_INIT(_W32_init_helper_##FI)
+ void __cdecl _W32_deinit_helper_ ## FD (void) \
+ { (void) (FD) (); } \
+ int __cdecl _W32_init_helper_ ## FI (void) \
+ { (void) (FI) (); atexit (_W32_deinit_helper_ ## FD); return 0; } \
+ W32_REGISTER_INIT (_W32_init_helper_ ## FI)
#else /* _USRDLL */
-/* If DllMain is already present in code, define AUTOINIT_FUNCS_CALL_USR_DLLMAIN
+/* If DllMain is already present in code, define AUTOINIT_FUNCS_CALL_USR_DLLMAIN
and rename DllMain to usr_DllMain */
#ifndef AUTOINIT_FUNCS_CALL_USR_DLLMAIN
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
- BOOL WINAPI DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused) \
- { if(DLL_PROCESS_ATTACH==reason) {(void)(FI)();} \
- else if(DLL_PROCESS_DETACH==reason) {(void)(FD)();} \
- return TRUE; \
- } struct _W32_dummy_strc_##FI{int i;}
+ BOOL WINAPI DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused) \
+ { if (DLL_PROCESS_ATTACH==reason) {(void) (FI) ();} \
+ else if (DLL_PROCESS_DETACH==reason) {(void) (FD) ();} \
+ return TRUE; \
+ } struct _W32_dummy_strc_ ## FI {int i;}
#else /* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
- BOOL WINAPI usr_DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused); \
- BOOL WINAPI DllMain(HINSTANCE hinst,DWORD reason,LPVOID unused) \
- { if(DLL_PROCESS_ATTACH==reason) {(void)(FI)();} \
- else if(DLL_PROCESS_DETACH==reason) {(void)(FD)();} \
- return usr_DllMain(hinst,reason,unused); \
- } struct _W32_dummy_strc_##FI{int i;}
+ BOOL WINAPI usr_DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused); \
+ BOOL WINAPI DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused) \
+ { if (DLL_PROCESS_ATTACH==reason) {(void) (FI) ();} \
+ else if (DLL_PROCESS_DETACH==reason) {(void) (FD) ();} \
+ return usr_DllMain (hinst,reason,unused); \
+ } struct _W32_dummy_strc_ ## FI {int i;}
#endif /* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
#endif /* _USRDLL */
-#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) W32_SET_INIT_AND_DEINIT(FI,FD)
+#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) W32_SET_INIT_AND_DEINIT (FI,FD)
/* Indicate that automatic initializers/deinitializers are supported */
#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
@@ -235,7 +240,8 @@
/* Define EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED before inclusion of header to
abort compilation if automatic initializers/deinitializers are not supported */
#ifdef EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED
-#error Compiler/platform don not support automatic calls of user-defined initializer and deinitializer
+#error \
+ Compiler/platform don not support automatic calls of user-defined initializer and deinitializer
#endif /* EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED */
/* Do nothing */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/mhd_options.h
^
|
@@ -42,10 +42,9 @@
#define _(String) (String)
-
#ifndef _MHD_EXTERN
#if defined(BUILDING_MHD_LIB) && defined(_WIN32) && \
- (defined(DLL_EXPORT) || defined(MHD_W32DLL))
+ (defined(DLL_EXPORT) || defined(MHD_W32DLL))
#define _MHD_EXTERN __declspec(dllexport) extern
#else /* !BUILDING_MHD_LIB || !_WIN32 || (!DLL_EXPORT && !MHD_W32DLL) */
#define _MHD_EXTERN extern
@@ -57,13 +56,29 @@
headers. */
#ifdef FD_SETSIZE
/* FD_SETSIZE defined in command line or in MHD_config.h */
-#elif defined(_WIN32) && !defined(__CYGWIN__)
+#elif defined(_WIN32) || defined(__CYGWIN__)
/* Platform with WinSock and without overridden FD_SETSIZE */
-#define FD_SETSIZE 2048 /* Override default small value */
-#else /* !FD_SETSIZE && !WinSock*/
+#define FD_SETSIZE 2048 /* Override default small value (64) */
+#else /* !FD_SETSIZE && !W32 */
/* System default value of FD_SETSIZE is used */
#define _MHD_FD_SETSIZE_IS_DEFAULT 1
-#endif /* !FD_SETSIZE && !WinSock*/
+#endif /* !FD_SETSIZE && !W32 */
+
+#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) || \
+ defined(HAVE_DARWIN_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE)
+/* Have any supported sendfile() function. */
+#define _MHD_HAVE_SENDFILE
+#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE ||
+ HAVE_DARWIN_SENDFILE || HAVE_SOLARIS_SENDFILE */
+#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE)
+#define MHD_LINUX_SOLARIS_SENDFILE 1
+#endif /* HAVE_LINUX_SENDFILE || HAVE_SOLARIS_SENDFILE */
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+# ifndef MHD_USE_THREADS
+# define MHD_USE_THREADS 1
+# endif
+#endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
#if OS390
#define _OPEN_THREADS
@@ -72,9 +87,13 @@
#define _LP64
#endif
-#if defined(_WIN32)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+/* Declare POSIX-compatible names */
+#define _CRT_DECLARE_NONSTDC_NAMES 1
+/* Do not warn about POSIX name usage */
+#define _CRT_NONSTDC_NO_WARNINGS 1
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
+#define _WIN32_WINNT 0x0600
#else /* _WIN32_WINNT */
#if _WIN32_WINNT < 0x0501
#error "Headers for Windows XP or later are required"
@@ -84,13 +103,14 @@
/* Do not include unneeded parts of W32 headers. */
#define WIN32_LEAN_AND_MEAN 1
#endif /* !WIN32_LEAN_AND_MEAN */
-#endif /* _WIN32 */
+#endif /* _WIN32 && ! __CYGWIN__ */
#if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS)
#define RESTRICT __restrict__
#endif /* __VXWORKS__ || __vxworks || OS_VXWORKS */
-#if LINUX+0 && (defined(HAVE_SENDFILE64) || defined(HAVE_LSEEK64)) && ! defined(_LARGEFILE64_SOURCE)
+#if LINUX + 0 && (defined(HAVE_SENDFILE64) || defined(HAVE_LSEEK64)) && \
+ ! defined(_LARGEFILE64_SOURCE)
/* On Linux, special macro is required to enable definitions of some xxx64 functions */
#define _LARGEFILE64_SOURCE 1
#endif
@@ -101,22 +121,23 @@
#endif /* HAVE_C11_GMTIME_S */
#if defined(MHD_FAVOR_FAST_CODE) && defined(MHD_FAVOR_SMALL_CODE)
-#error MHD_FAVOR_FAST_CODE and MHD_FAVOR_SMALL_CODE are both defined. Cannot favor speed and size at the same time.
+#error \
+ MHD_FAVOR_FAST_CODE and MHD_FAVOR_SMALL_CODE are both defined. Cannot favor speed and size at the same time.
#endif /* MHD_FAVOR_FAST_CODE && MHD_FAVOR_SMALL_CODE */
/* Define MHD_FAVOR_FAST_CODE to force fast code path or
define MHD_FAVOR_SMALL_CODE to choose compact code path */
-#if !defined(MHD_FAVOR_FAST_CODE) && !defined(MHD_FAVOR_SMALL_CODE)
+#if ! defined(MHD_FAVOR_FAST_CODE) && ! defined(MHD_FAVOR_SMALL_CODE)
/* Try to detect user preferences */
/* Defined by GCC and many compatible compilers */
-#ifdef __OPTIMIZE_SIZE__
+#if defined(__OPTIMIZE_SIZE__)
#define MHD_FAVOR_SMALL_CODE 1
-#elif __OPTIMIZE__
+#elif defined(__OPTIMIZE__)
#define MHD_FAVOR_FAST_CODE 1
#endif /* __OPTIMIZE__ */
#endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */
-#if !defined(MHD_FAVOR_FAST_CODE) && !defined(MHD_FAVOR_SMALL_CODE)
+#if ! defined(MHD_FAVOR_FAST_CODE) && ! defined(MHD_FAVOR_SMALL_CODE)
/* Use faster code by default */
#define MHD_FAVOR_FAST_CODE 1
#endif /* !MHD_FAVOR_FAST_CODE && !MHD_FAVOR_SMALL_CODE */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/microhttpd.h
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2006-2017 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2006--2020 Christian Grothoff (and other contributing authors)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -43,7 +43,7 @@
*
* MHD understands POST data and is able to decode certain formats
* (at the moment only "application/x-www-form-urlencoded" and
- * "mulitpart/formdata"). Unsupported encodings and large POST
+ * "multipart/formdata"). Unsupported encodings and large POST
* submissions may require the application to manually process
* the stream, which is provided to the main application (and thus can be
* processed, just not conveniently by MHD).
@@ -87,12 +87,7 @@
#endif
#endif
-/* While we generally would like users to use a configure-driven
- build process which detects which headers are present and
- hence works on any platform, we use "standard" includes here
- to build out-of-the-box for beginning users on common systems.
-
- If generic headers don't work on your platform, include headers
+/* If generic headers don't work on your platform, include headers
which define 'va_list', 'size_t', 'ssize_t', 'intptr_t',
'uint16_t', 'uint32_t', 'uint64_t', 'off_t', 'struct sockaddr',
'socklen_t', 'fd_set' and "#define MHD_PLATFORM_H" before
@@ -101,42 +96,59 @@
on platforms where they do not exist).
*/
#ifndef MHD_PLATFORM_H
+#if defined(_WIN32) && ! defined(__CYGWIN__) && \
+ ! defined(_CRT_DECLARE_NONSTDC_NAMES)
+#define _CRT_DECLARE_NONSTDC_NAMES 1
+#endif /* _WIN32 && ! __CYGWIN__ && ! _CRT_DECLARE_NONSTDC_NAMES */
#include <stdarg.h>
#include <stdint.h>
#include <sys/types.h>
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#else /* _WIN32 && ! __CYGWIN__ */
+/* Declare POSIX-compatible names */
+#define _CRT_DECLARE_NONSTDC_NAMES 1
#include <ws2tcpip.h>
-#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
+#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
#define _SSIZE_T_DEFINED
typedef intptr_t ssize_t;
#endif /* !_SSIZE_T_DEFINED */
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#endif
+#endif /* _WIN32 && ! __CYGWIN__ */
#endif
-#if defined(__CYGWIN__) && !defined(_SYS_TYPES_FD_SET)
+#if defined(__CYGWIN__) && ! defined(_SYS_TYPES_FD_SET)
/* Do not define __USE_W32_SOCKETS under Cygwin! */
#error Cygwin with winsock fd_set is not supported
#endif
/**
- * Current version of the library.
- * 0x01093001 = 1.9.30-1.
+ * Current version of the library in packed BCD form.
+ * @note Version number components are coded as Simple Binary-Coded Decimal
+ * (also called Natural BCD or BCD 8421). While they are hexadecimal numbers,
+ * they are parsed as decimal numbers.
+ * Example: 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00095500
+#define MHD_VERSION 0x00097300
/**
- * MHD-internal return code for "YES".
+ * Operational results from MHD calls.
*/
-#define MHD_YES 1
+enum MHD_Result
+{
+ /**
+ * MHD result code for "NO".
+ */
+ MHD_NO = 0,
+
+ /**
+ * MHD result code for "YES".
+ */
+ MHD_YES = 1
+
+};
-/**
- * MHD-internal return code for "NO".
- */
-#define MHD_NO 0
/**
* MHD digest auth internal code for an invalid nonce.
@@ -176,7 +188,7 @@
/**
* MHD_socket is type for socket FDs
*/
-#if !defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
+#if ! defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
#define MHD_POSIX_SOCKETS 1
typedef int MHD_socket;
#define MHD_INVALID_SOCKET (-1)
@@ -201,30 +213,35 @@
#endif /* MHD_NO_DEPRECATION */
#ifndef _MHD_DEPR_MACRO
-#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1500
+#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1500
/* VS 2008 or later */
/* Stringify macros */
#define _MHD_INSTRMACRO(a) #a
-#define _MHD_STRMACRO(a) _MHD_INSTRMACRO(a)
+#define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a)
/* deprecation message */
-#define _MHD_DEPR_MACRO(msg) __pragma(message(__FILE__ "(" _MHD_STRMACRO(__LINE__)"): warning: " msg))
-#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
+#define _MHD_DEPR_MACRO(msg) __pragma(message (__FILE__ "(" _MHD_STRMACRO ( \
+ __LINE__) "): warning: " msg))
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
#elif defined(__clang__) || defined (__GNUC_PATCHLEVEL__)
/* clang or GCC since 3.0 */
-#define _MHD_GCC_PRAG(x) _Pragma (#x)
-#if __clang_major__+0 >= 5 || \
- (!defined(__apple_build_version__) && (__clang_major__+0 > 3 || (__clang_major__+0 == 3 && __clang_minor__ >= 3))) || \
- __GNUC__+0 > 4 || (__GNUC__+0 == 4 && __GNUC_MINOR__+0 >= 8)
+#define _MHD_GCC_PRAG(x) _Pragma(#x)
+#if (defined(__clang__) && (__clang_major__ + 0 >= 5 || \
+ (! defined(__apple_build_version__) && \
+ (__clang_major__ + 0 > 3 || (__clang_major__ + 0 == 3 && __clang_minor__ >= \
+ 3))))) || \
+ __GNUC__ + 0 > 4 || (__GNUC__ + 0 == 4 && __GNUC_MINOR__ + 0 >= 8)
/* clang >= 3.3 (or XCode's clang >= 5.0) or
GCC >= 4.8 */
-#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(GCC warning msg)
-#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
+#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (GCC warning msg)
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
#else /* older clang or GCC */
/* clang < 3.3, XCode's clang < 5.0, 3.0 <= GCC < 4.8 */
-#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(message msg)
-#if (__clang_major__+0 > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9)) /* FIXME: clang >= 2.9, earlier versions not tested */
+#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (message msg)
+#if (defined(__clang__) && (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == \
+ 2 && __clang_minor__ >= \
+ 9))) /* FIXME: clang >= 2.9, earlier versions not tested */
/* clang handles inline pragmas better than GCC */
-#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO(msg)
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
#endif /* clang >= 2.9 */
#endif /* older clang or GCC */
/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
@@ -241,17 +258,19 @@
#endif /* !_MHD_DEPR_IN_MACRO */
#ifndef _MHD_DEPR_FUNC
-#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1400
+#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1400
/* VS 2005 or later */
-#define _MHD_DEPR_FUNC(msg) __declspec(deprecated(msg))
-#elif defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1310
+#define _MHD_DEPR_FUNC(msg) __declspec(deprecated (msg))
+#elif defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1310
/* VS .NET 2003 deprecation do not support custom messages */
#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)
-#elif (__GNUC__+0 >= 5) || (defined (__clang__) && \
- (__clang_major__+0 > 2 || (__clang_major__+0 == 2 && __clang_minor__ >= 9))) /* FIXME: earlier versions not tested */
+#elif (__GNUC__ + 0 >= 5) || (defined (__clang__) && \
+ (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == 2 && __clang_minor__ >= \
+ 9))) /* FIXME: earlier versions not tested */
/* GCC >= 5.0 or clang >= 2.9 */
-#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated(msg)))
-#elif defined (__clang__) || __GNUC__+0 > 3 || (__GNUC__+0 == 3 && __GNUC_MINOR__+0 >= 1)
+#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated (msg)))
+#elif defined (__clang__) || __GNUC__ + 0 > 3 || (__GNUC__ + 0 == 3 && \
+ __GNUC_MINOR__ + 0 >= 1)
/* 3.1 <= GCC < 5.0 or clang < 2.9 */
/* old GCC-style deprecation do not support custom messages */
#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__))
@@ -276,7 +295,8 @@
#define MHD_LONG_LONG long long
#define MHD_UNSIGNED_LONG_LONG unsigned long long
#else /* MHD_LONG_LONG */
-_MHD_DEPR_MACRO("Macro MHD_LONG_LONG is deprecated, use MHD_UNSIGNED_LONG_LONG")
+_MHD_DEPR_MACRO (
+ "Macro MHD_LONG_LONG is deprecated, use MHD_UNSIGNED_LONG_LONG")
#endif
/**
* Format string for printing a variable of type #MHD_LONG_LONG.
@@ -289,111 +309,217 @@
#define MHD_LONG_LONG_PRINTF "ll"
#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu"
#else /* MHD_LONG_LONG_PRINTF */
-_MHD_DEPR_MACRO("Macro MHD_LONG_LONG_PRINTF is deprecated, use MHD_UNSIGNED_LONG_LONG_PRINTF")
+_MHD_DEPR_MACRO (
+ "Macro MHD_LONG_LONG_PRINTF is deprecated, use MHD_UNSIGNED_LONG_LONG_PRINTF")
#endif
/**
+ * Length of the binary output of the MD5 hash function.
+ */
+#define MHD_MD5_DIGEST_SIZE 16
+
+
+/**
* @defgroup httpcode HTTP response codes.
* These are the status codes defined for HTTP responses.
+ * See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * Registry export date: 2019-06-09
* @{
*/
-/* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
+/* 100 "Continue". RFC7231, Section 6.2.1. */
#define MHD_HTTP_CONTINUE 100
+/* 101 "Switching Protocols". RFC7231, Section 6.2.2. */
#define MHD_HTTP_SWITCHING_PROTOCOLS 101
+/* 102 "Processing". RFC2518. */
#define MHD_HTTP_PROCESSING 102
+/* 103 "Early Hints". RFC8297. */
+#define MHD_HTTP_EARLY_HINTS 103
+/* 200 "OK". RFC7231, Section 6.3.1. */
#define MHD_HTTP_OK 200
+/* 201 "Created". RFC7231, Section 6.3.2. */
#define MHD_HTTP_CREATED 201
+/* 202 "Accepted". RFC7231, Section 6.3.3. */
#define MHD_HTTP_ACCEPTED 202
+/* 203 "Non-Authoritative Information". RFC7231, Section 6.3.4. */
#define MHD_HTTP_NON_AUTHORITATIVE_INFORMATION 203
+/* 204 "No Content". RFC7231, Section 6.3.5. */
#define MHD_HTTP_NO_CONTENT 204
+/* 205 "Reset Content". RFC7231, Section 6.3.6. */
#define MHD_HTTP_RESET_CONTENT 205
+/* 206 "Partial Content". RFC7233, Section 4.1. */
#define MHD_HTTP_PARTIAL_CONTENT 206
+/* 207 "Multi-Status". RFC4918. */
#define MHD_HTTP_MULTI_STATUS 207
+/* 208 "Already Reported". RFC5842. */
#define MHD_HTTP_ALREADY_REPORTED 208
+/* 226 "IM Used". RFC3229. */
#define MHD_HTTP_IM_USED 226
+/* 300 "Multiple Choices". RFC7231, Section 6.4.1. */
#define MHD_HTTP_MULTIPLE_CHOICES 300
+/* 301 "Moved Permanently". RFC7231, Section 6.4.2. */
#define MHD_HTTP_MOVED_PERMANENTLY 301
+/* 302 "Found". RFC7231, Section 6.4.3. */
#define MHD_HTTP_FOUND 302
+/* 303 "See Other". RFC7231, Section 6.4.4. */
#define MHD_HTTP_SEE_OTHER 303
+/* 304 "Not Modified". RFC7232, Section 4.1. */
#define MHD_HTTP_NOT_MODIFIED 304
+/* 305 "Use Proxy". RFC7231, Section 6.4.5. */
#define MHD_HTTP_USE_PROXY 305
+/* 306 "Switch Proxy". Not used! RFC7231, Section 6.4.6. */
#define MHD_HTTP_SWITCH_PROXY 306
+/* 307 "Temporary Redirect". RFC7231, Section 6.4.7. */
#define MHD_HTTP_TEMPORARY_REDIRECT 307
+/* 308 "Permanent Redirect". RFC7538. */
#define MHD_HTTP_PERMANENT_REDIRECT 308
+/* 400 "Bad Request". RFC7231, Section 6.5.1. */
#define MHD_HTTP_BAD_REQUEST 400
+/* 401 "Unauthorized". RFC7235, Section 3.1. */
#define MHD_HTTP_UNAUTHORIZED 401
+/* 402 "Payment Required". RFC7231, Section 6.5.2. */
#define MHD_HTTP_PAYMENT_REQUIRED 402
+/* 403 "Forbidden". RFC7231, Section 6.5.3. */
#define MHD_HTTP_FORBIDDEN 403
+/* 404 "Not Found". RFC7231, Section 6.5.4. */
#define MHD_HTTP_NOT_FOUND 404
+/* 405 "Method Not Allowed". RFC7231, Section 6.5.5. */
#define MHD_HTTP_METHOD_NOT_ALLOWED 405
+/* 406 "Not Acceptable". RFC7231, Section 6.5.6. */
#define MHD_HTTP_NOT_ACCEPTABLE 406
-/** @deprecated */
-#define MHD_HTTP_METHOD_NOT_ACCEPTABLE \
- _MHD_DEPR_IN_MACRO("Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE") 406
+/* 407 "Proxy Authentication Required". RFC7235, Section 3.2. */
#define MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED 407
+/* 408 "Request Timeout". RFC7231, Section 6.5.7. */
#define MHD_HTTP_REQUEST_TIMEOUT 408
+/* 409 "Conflict". RFC7231, Section 6.5.8. */
#define MHD_HTTP_CONFLICT 409
+/* 410 "Gone". RFC7231, Section 6.5.9. */
#define MHD_HTTP_GONE 410
+/* 411 "Length Required". RFC7231, Section 6.5.10. */
#define MHD_HTTP_LENGTH_REQUIRED 411
+/* 412 "Precondition Failed". RFC7232, Section 4.2; RFC8144, Section 3.2. */
#define MHD_HTTP_PRECONDITION_FAILED 412
+/* 413 "Payload Too Large". RFC7231, Section 6.5.11. */
#define MHD_HTTP_PAYLOAD_TOO_LARGE 413
-/** @deprecated */
-#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE \
- _MHD_DEPR_IN_MACRO("Value MHD_HTTP_REQUEST_ENTITY_TOO_LARGE is deprecated, use MHD_HTTP_PAYLOAD_TOO_LARGE") 413
+/* 414 "URI Too Long". RFC7231, Section 6.5.12. */
#define MHD_HTTP_URI_TOO_LONG 414
-/** @deprecated */
-#define MHD_HTTP_REQUEST_URI_TOO_LONG \
- _MHD_DEPR_IN_MACRO("Value MHD_HTTP_REQUEST_URI_TOO_LONG is deprecated, use MHD_HTTP_URI_TOO_LONG") 414
+/* 415 "Unsupported Media Type". RFC7231, Section 6.5.13; RFC7694, Section 3. */
#define MHD_HTTP_UNSUPPORTED_MEDIA_TYPE 415
+/* 416 "Range Not Satisfiable". RFC7233, Section 4.4. */
#define MHD_HTTP_RANGE_NOT_SATISFIABLE 416
-/** @deprecated */
-#define MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE \
- _MHD_DEPR_IN_MACRO("Value MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE is deprecated, use MHD_HTTP_RANGE_NOT_SATISFIABLE") 416
+/* 417 "Expectation Failed". RFC7231, Section 6.5.14. */
#define MHD_HTTP_EXPECTATION_FAILED 417
+/* 421 "Misdirected Request". RFC7540, Section 9.1.2. */
#define MHD_HTTP_MISDIRECTED_REQUEST 421
+/* 422 "Unprocessable Entity". RFC4918. */
#define MHD_HTTP_UNPROCESSABLE_ENTITY 422
+/* 423 "Locked". RFC4918. */
#define MHD_HTTP_LOCKED 423
+/* 424 "Failed Dependency". RFC4918. */
#define MHD_HTTP_FAILED_DEPENDENCY 424
-#define MHD_HTTP_UNORDERED_COLLECTION 425
+/* 425 "Too Early". RFC8470. */
+#define MHD_HTTP_TOO_EARLY 425
+/* 426 "Upgrade Required". RFC7231, Section 6.5.15. */
#define MHD_HTTP_UPGRADE_REQUIRED 426
+/* 428 "Precondition Required". RFC6585. */
#define MHD_HTTP_PRECONDITION_REQUIRED 428
+/* 429 "Too Many Requests". RFC6585. */
#define MHD_HTTP_TOO_MANY_REQUESTS 429
-#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 431
-#define MHD_HTTP_NO_RESPONSE 444
+/* 431 "Request Header Fields Too Large". RFC6585. */
+#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 431
-#define MHD_HTTP_RETRY_WITH 449
-#define MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450
+/* 451 "Unavailable For Legal Reasons". RFC7725. */
#define MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS 451
+/* 500 "Internal Server Error". RFC7231, Section 6.6.1. */
#define MHD_HTTP_INTERNAL_SERVER_ERROR 500
+/* 501 "Not Implemented". RFC7231, Section 6.6.2. */
#define MHD_HTTP_NOT_IMPLEMENTED 501
+/* 502 "Bad Gateway". RFC7231, Section 6.6.3. */
#define MHD_HTTP_BAD_GATEWAY 502
+/* 503 "Service Unavailable". RFC7231, Section 6.6.4. */
#define MHD_HTTP_SERVICE_UNAVAILABLE 503
+/* 504 "Gateway Timeout". RFC7231, Section 6.6.5. */
#define MHD_HTTP_GATEWAY_TIMEOUT 504
+/* 505 "HTTP Version Not Supported". RFC7231, Section 6.6.6. */
#define MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED 505
+/* 506 "Variant Also Negotiates". RFC2295. */
#define MHD_HTTP_VARIANT_ALSO_NEGOTIATES 506
+/* 507 "Insufficient Storage". RFC4918. */
#define MHD_HTTP_INSUFFICIENT_STORAGE 507
+/* 508 "Loop Detected". RFC5842. */
#define MHD_HTTP_LOOP_DETECTED 508
-#define MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509
+
+/* 510 "Not Extended". RFC2774. */
#define MHD_HTTP_NOT_EXTENDED 510
+/* 511 "Network Authentication Required". RFC6585. */
#define MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED 511
+
+/* Not registered non-standard codes */
+/* 449 "Reply With". MS IIS extension. */
+#define MHD_HTTP_RETRY_WITH 449
+
+/* 450 "Blocked by Windows Parental Controls". MS extension. */
+#define MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS 450
+
+/* 509 "Bandwidth Limit Exceeded". Apache extension. */
+#define MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED 509
+
+
+/* Deprecated codes */
+/** @deprecated */
+#define MHD_HTTP_METHOD_NOT_ACCEPTABLE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE") \
+ 406
+
+/** @deprecated */
+#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUEST_ENTITY_TOO_LARGE is deprecated, use MHD_HTTP_PAYLOAD_TOO_LARGE") \
+ 413
+
+/** @deprecated */
+#define MHD_HTTP_REQUEST_URI_TOO_LONG \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUEST_URI_TOO_LONG is deprecated, use MHD_HTTP_URI_TOO_LONG") \
+ 414
+
+/** @deprecated */
+#define MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE is deprecated, use MHD_HTTP_RANGE_NOT_SATISFIABLE") \
+ 416
+
+/** @deprecated */
+#define MHD_HTTP_UNORDERED_COLLECTION \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_UNORDERED_COLLECTION is deprecated as it was removed from RFC") \
+ 425
+
+/** @deprecated */
+#define MHD_HTTP_NO_RESPONSE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_NO_RESPONSE is deprecated as it is nginx internal code for logs only") \
+ 444
+
+
/** @} */ /* end of group httpcode */
/**
* Returns the string reason phrase for a response code.
*
- * If we don't have a string for a status code, we give the first
- * message in that status code class.
+ * If message string is not available for a status code,
+ * "Unknown" string will be returned.
*/
_MHD_EXTERN const char *
MHD_get_reason_phrase_for (unsigned int code);
@@ -402,16 +528,16 @@
/**
* Flag to be or-ed with MHD_HTTP status code for
* SHOUTcast. This will cause the response to begin
- * with the SHOUTcast "ICY" line instad of "HTTP".
+ * with the SHOUTcast "ICY" line instead of "HTTP".
* @ingroup specialized
*/
-#define MHD_ICY_FLAG ((uint32_t)(((uint32_t)1) << 31))
+#define MHD_ICY_FLAG ((uint32_t) (((uint32_t) 1) << 31))
/**
* @defgroup headers HTTP headers
* These are the standard headers found in HTTP requests and responses.
* See: http://www.iana.org/assignments/message-headers/message-headers.xml
- * Registry Version 2017-01-27
+ * Registry export date: 2020-09-20
* @{
*/
@@ -518,12 +644,16 @@
#define MHD_HTTP_HEADER_A_IM "A-IM"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
+/* Experimental. RFC-ietf-httpbis-client-hints-15, Section 3.1 */
+#define MHD_HTTP_HEADER_ACCEPT_CH "Accept-CH"
/* Informational. RFC7089 */
#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
/* No category. RFC5789 */
#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
+/* Standard. https://www.w3.org/TR/ldp/ */
+#define MHD_HTTP_HEADER_ACCEPT_POST "Accept-Post"
/* Standard. RFC7639, Section 2 */
#define MHD_HTTP_HEADER_ALPN "ALPN"
/* Standard. RFC7838 */
@@ -548,8 +678,16 @@
#define MHD_HTTP_HEADER_C_PEP "C-PEP"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info"
+/* Standard. RFC8607, Section 5.1 */
+#define MHD_HTTP_HEADER_CAL_MANAGED_ID "Cal-Managed-ID"
/* Standard. RFC7809, Section 7.1 */
#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
+/* Standard. RFC8586 */
+#define MHD_HTTP_HEADER_CDN_LOOP "CDN-Loop"
+/* Standard. RFC8739, Section 3.3 */
+#define MHD_HTTP_HEADER_CERT_NOT_AFTER "Cert-Not-After"
+/* Standard. RFC8739, Section 3.3 */
+#define MHD_HTTP_HEADER_CERT_NOT_BEFORE "Cert-Not-Before"
/* Obsoleted. RFC2068; RFC2616 */
#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
/* Standard. RFC6266 */
@@ -586,6 +724,10 @@
#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_DIGEST "Digest"
+/* Standard. RFC8470 */
+#define MHD_HTTP_HEADER_EARLY_DATA "Early-Data"
+/* Experimental. RFC-ietf-httpbis-expect-ct-08 */
+#define MHD_HTTP_HEADER_EXPECT_CT "Expect-CT"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_EXT "Ext"
/* Standard. RFC7239 */
@@ -602,11 +744,14 @@
#define MHD_HTTP_HEADER_IF "If"
/* Standard. RFC6638 */
#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
+/* Standard. RFC8473 */
+#define MHD_HTTP_HEADER_INCLUDE_REFERRED_TOKEN_BINDING_ID \
+ "Include-Referred-Token-Binding-ID"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_LABEL "Label"
-/* No category. RFC5988 */
+/* Standard. RFC8288 */
#define MHD_HTTP_HEADER_LINK "Link"
/* Standard. RFC4918 */
#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token"
@@ -618,6 +763,14 @@
#define MHD_HTTP_HEADER_METER "Meter"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate"
+/* Standard. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
+#define MHD_HTTP_HEADER_ODATA_ENTITYID "OData-EntityId"
+/* Standard. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
+#define MHD_HTTP_HEADER_ODATA_ISOLATION "OData-Isolation"
+/* Standard. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
+#define MHD_HTTP_HEADER_ODATA_MAXVERSION "OData-MaxVersion"
+/* Standard. OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
+#define MHD_HTTP_HEADER_ODATA_VERSION "OData-Version"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_OPT "Opt"
/* Experimental. RFC8053, Section 3 */
@@ -626,6 +779,8 @@
#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
/* Standard. RFC6454 */
#define MHD_HTTP_HEADER_ORIGIN "Origin"
+/* Standard. RFC8613, Section 11.1 */
+#define MHD_HTTP_HEADER_OSCORE "OSCORE"
/* Standard. RFC4918 */
#define MHD_HTTP_HEADER_OVERWRITE "Overwrite"
/* No category. RFC4229 */
@@ -663,15 +818,20 @@
/* Standard. RFC7469 */
#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
/* Standard. RFC7469 */
-#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY "Public-Key-Pins-Report-Only"
+#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \
+ "Public-Key-Pins-Report-Only"
/* No category. RFC4437 */
#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
+/* Standard. RFC8555, Section 6.5.1 */
+#define MHD_HTTP_HEADER_REPLAY_NONCE "Replay-Nonce"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_SAFE "Safe"
/* Standard. RFC6638 */
#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
/* Standard. RFC6638 */
#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
+/* Standard. RFC8473 */
+#define MHD_HTTP_HEADER_SEC_TOKEN_BINDING "Sec-Token-Binding"
/* Standard. RFC6455 */
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
/* Standard. RFC6455 */
@@ -698,6 +858,8 @@
#define MHD_HTTP_HEADER_STATUS_URI "Status-URI"
/* Standard. RFC6797 */
#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
+/* Informational. RFC8594 */
+#define MHD_HTTP_HEADER_SUNSET "Sunset"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
/* No category. RFC4229 */
@@ -718,11 +880,14 @@
#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
/* No category. RFC4229 */
#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest"
+/* Standard. https://fetch.spec.whatwg.org/#x-content-type-options-header */
+#define MHD_HTTP_HEADER_X_CONTENT_TYPE_OPTIONS "X-Content-Type-Options"
/* Informational. RFC7034 */
#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
/* Some provisional headers. */
-#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN "Access-Control-Allow-Origin"
+#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \
+ "Access-Control-Allow-Origin"
/** @} */ /* end of group headers */
/**
@@ -740,9 +905,10 @@
* @defgroup methods HTTP methods
* HTTP methods (as strings).
* See: http://www.iana.org/assignments/http-methods/http-methods.xml
- * Registry Version 2015-05-19
+ * Registry export date: 2020-09-20
* @{
*/
+
/* Main HTTP methods. */
/* Not safe. Not idempotent. RFC7231, Section 4.3.6. */
#define MHD_HTTP_METHOD_CONNECT "CONNECT"
@@ -784,9 +950,9 @@
#define MHD_HTTP_METHOD_MERGE "MERGE"
/* Not safe. Idempotent. RFC3253, Section 13.5. */
#define MHD_HTTP_METHOD_MKACTIVITY "MKACTIVITY"
-/* Not safe. Idempotent. RFC4791, Section 5.3.1. */
+/* Not safe. Idempotent. RFC4791, Section 5.3.1; RFC8144, Section 2.3. */
#define MHD_HTTP_METHOD_MKCALENDAR "MKCALENDAR"
-/* Not safe. Idempotent. RFC4918, Section 9.3. */
+/* Not safe. Idempotent. RFC4918, Section 9.3; RFC5689, Section 3; RFC8144, Section 2.3. */
#define MHD_HTTP_METHOD_MKCOL "MKCOL"
/* Not safe. Idempotent. RFC4437, Section 6. */
#define MHD_HTTP_METHOD_MKREDIRECTREF "MKREDIRECTREF"
@@ -800,13 +966,13 @@
#define MHD_HTTP_METHOD_PATCH "PATCH"
/* Safe. Idempotent. RFC7540, Section 3.5. */
#define MHD_HTTP_METHOD_PRI "PRI"
-/* Safe. Idempotent. RFC4918, Section 9.1. */
+/* Safe. Idempotent. RFC4918, Section 9.1; RFC8144, Section 2.1. */
#define MHD_HTTP_METHOD_PROPFIND "PROPFIND"
-/* Not safe. Idempotent. RFC4918, Section 9.2. */
+/* Not safe. Idempotent. RFC4918, Section 9.2; RFC8144, Section 2.2. */
#define MHD_HTTP_METHOD_PROPPATCH "PROPPATCH"
/* Not safe. Idempotent. RFC5842, Section 6. */
#define MHD_HTTP_METHOD_REBIND "REBIND"
-/* Safe. Idempotent. RFC3253, Section 3.6. */
+/* Safe. Idempotent. RFC3253, Section 3.6; RFC8144, Section 2.1. */
#define MHD_HTTP_METHOD_REPORT "REPORT"
/* Safe. Idempotent. RFC5323, Section 2. */
#define MHD_HTTP_METHOD_SEARCH "SEARCH"
@@ -832,7 +998,8 @@
* See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
* @{
*/
-#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED "application/x-www-form-urlencoded"
+#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED \
+ "application/x-www-form-urlencoded"
#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data"
/** @} */ /* end of group postenc */
@@ -909,7 +1076,7 @@
#if 0
/* let's do this later once versions that define MHD_USE_TLS a more widely deployed. */
#define MHD_USE_SSL \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_SSL is deprecated, use MHD_USE_TLS") \
+ _MHD_DEPR_IN_MACRO ("Value MHD_USE_SSL is deprecated, use MHD_USE_TLS") \
MHD_USE_TLS
#endif
@@ -934,7 +1101,8 @@
MHD_USE_SELECT_INTERNALLY = 8,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_SELECT_INTERNALLY \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_SELECT_INTERNALLY is deprecated, use MHD_USE_INTERNAL_POLLING_THREAD instead") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_SELECT_INTERNALLY is deprecated, use MHD_USE_INTERNAL_POLLING_THREAD instead") \
MHD_USE_INTERNAL_POLLING_THREAD
#endif /* 0 */
@@ -959,7 +1127,8 @@
MHD_USE_PEDANTIC_CHECKS = 32,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_PEDANTIC_CHECKS \
- _MHD_DEPR_IN_MACRO("Flag MHD_USE_PEDANTIC_CHECKS is deprecated, use option MHD_OPTION_STRICT_FOR_CLIENT instead") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, use option MHD_OPTION_STRICT_FOR_CLIENT instead") \
32
#endif /* 0 */
@@ -983,7 +1152,8 @@
MHD_USE_POLL_INTERNALLY = MHD_USE_POLL | MHD_USE_INTERNAL_POLLING_THREAD,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_POLL_INTERNALLY \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_POLL_INTERNALLY is deprecated, use MHD_USE_POLL_INTERNAL_THREAD instead") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_POLL_INTERNALLY is deprecated, use MHD_USE_POLL_INTERNAL_THREAD instead") \
MHD_USE_POLL_INTERNAL_THREAD
#endif /* 0 */
@@ -999,7 +1169,8 @@
MHD_SUPPRESS_DATE_NO_CLOCK = 128,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_SUPPRESS_DATE_NO_CLOCK \
- _MHD_DEPR_IN_MACRO("Value MHD_SUPPRESS_DATE_NO_CLOCK is deprecated, use MHD_USE_SUPPRESS_DATE_NO_CLOCK instead") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_SUPPRESS_DATE_NO_CLOCK is deprecated, use MHD_USE_SUPPRESS_DATE_NO_CLOCK instead") \
MHD_USE_SUPPRESS_DATE_NO_CLOCK
#endif /* 0 */
@@ -1025,7 +1196,8 @@
MHD_USE_EPOLL_LINUX_ONLY = 512,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_EPOLL_LINUX_ONLY \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_EPOLL_LINUX_ONLY is deprecated, use MHD_USE_EPOLL") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_EPOLL_LINUX_ONLY is deprecated, use MHD_USE_EPOLL") \
MHD_USE_EPOLL
#endif /* 0 */
@@ -1035,19 +1207,23 @@
* platform without `epoll` support will cause #MHD_start_daemon to fail.
* @sa ::MHD_FEATURE_EPOLL, #MHD_USE_EPOLL, #MHD_USE_INTERNAL_POLLING_THREAD
*/
- MHD_USE_EPOLL_INTERNAL_THREAD = MHD_USE_EPOLL | MHD_USE_INTERNAL_POLLING_THREAD,
+ MHD_USE_EPOLL_INTERNAL_THREAD = MHD_USE_EPOLL
+ | MHD_USE_INTERNAL_POLLING_THREAD,
/** @deprecated */
MHD_USE_EPOLL_INTERNALLY = MHD_USE_EPOLL | MHD_USE_INTERNAL_POLLING_THREAD,
/** @deprecated */
- MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY = MHD_USE_EPOLL | MHD_USE_INTERNAL_POLLING_THREAD,
+ MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY = MHD_USE_EPOLL
+ | MHD_USE_INTERNAL_POLLING_THREAD,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_EPOLL_INTERNALLY \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_EPOLL_INTERNALLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_EPOLL_INTERNALLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \
MHD_USE_EPOLL_INTERNAL_THREAD
/** @deprecated */
#define MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY is deprecated, use MHD_USE_EPOLL_INTERNAL_THREAD") \
MHD_USE_EPOLL_INTERNAL_THREAD
#endif /* 0 */
@@ -1069,7 +1245,8 @@
MHD_USE_PIPE_FOR_SHUTDOWN = 1024,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_PIPE_FOR_SHUTDOWN \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_PIPE_FOR_SHUTDOWN is deprecated, use MHD_USE_ITC") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_PIPE_FOR_SHUTDOWN is deprecated, use MHD_USE_ITC") \
MHD_USE_ITC
#endif /* 0 */
@@ -1090,7 +1267,8 @@
MHD_USE_EPOLL_TURBO = 4096,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_EPOLL_TURBO \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_EPOLL_TURBO is deprecated, use MHD_USE_TURBO") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_EPOLL_TURBO is deprecated, use MHD_USE_TURBO") \
MHD_USE_TURBO
#endif /* 0 */
@@ -1104,7 +1282,8 @@
MHD_USE_SUSPEND_RESUME = 8192 | MHD_USE_ITC,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_SUSPEND_RESUME \
- _MHD_DEPR_IN_MACRO("Value MHD_USE_SUSPEND_RESUME is deprecated, use MHD_ALLOW_SUSPEND_RESUME instead") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_USE_SUSPEND_RESUME is deprecated, use MHD_ALLOW_SUSPEND_RESUME instead") \
MHD_ALLOW_SUSPEND_RESUME
#endif /* 0 */
@@ -1141,7 +1320,19 @@
* This is combination of #MHD_USE_AUTO and #MHD_USE_INTERNAL_POLLING_THREAD
* flags.
*/
- MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+
+ /**
+ * Flag set to enable post-handshake client authentication
+ * (only useful in combination with #MHD_USE_TLS).
+ */
+ MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT = 1U << 17,
+
+ /**
+ * Flag set to enable TLS 1.3 early data. This has
+ * security implications, be VERY careful when using this.
+ */
+ MHD_USE_INSECURE_TLS_EARLY_DATA = 1U << 18
};
@@ -1161,6 +1352,25 @@
/**
+ * Function called to lookup the pre shared key (@a psk) for a given
+ * HTTP connection based on the @a username.
+ *
+ * @param cls closure
+ * @param connection the HTTPS connection
+ * @param username the user name claimed by the other side
+ * @param[out] psk to be set to the pre-shared-key; should be allocated with malloc(),
+ * will be freed by MHD
+ * @param[out] psk_size to be set to the number of bytes in @a psk
+ * @return 0 on success, -1 on errors
+ */
+typedef int
+(*MHD_PskServerCredentialsCallback)(void *cls,
+ const struct MHD_Connection *connection,
+ const char *username,
+ void **psk,
+ size_t *psk_size);
+
+/**
* @brief MHD options.
*
* Passed in the varargs portion of #MHD_start_daemon.
@@ -1305,6 +1515,8 @@
* a function of type #MHD_LogCallback and the second a pointer
* `void *` which will be passed as the first argument to the log
* callback.
+ * Should be specified as the first option, otherwise some messages
+ * may be printed by standard MHD logger during daemon startup.
*
* Note that MHD will not generate any log messages
* if it was compiled without the "--enable-messages"
@@ -1315,10 +1527,10 @@
/**
* Number (`unsigned int`) of threads in thread pool. Enable
* thread pooling by setting this value to to something
- * greater than 1. Currently, thread model must be
+ * greater than 1. Currently, thread mode must be
* #MHD_USE_INTERNAL_POLLING_THREAD if thread pooling is enabled
* (#MHD_start_daemon returns NULL for an unsupported thread
- * model).
+ * mode).
*/
MHD_OPTION_THREAD_POOL_SIZE = 14,
@@ -1355,10 +1567,12 @@
* struct MHD_Connection *c,
* char *s)
*
- * where the return value must be "strlen(s)" and "s" should be
- * updated. Note that the unescape function must not lengthen "s"
- * (the result must be shorter than the input and still be
- * 0-terminated). "cls" will be set to the second argument
+ * where the return value must be the length of the value left in
+ * "s" (without the 0-terminator) and "s" should be updated. Note
+ * that the unescape function must not lengthen "s" (the result must
+ * be shorter than the input and must still be 0-terminated).
+ * However, it may also include binary zeros before the
+ * 0-termination. "cls" will be set to the second argument
* following #MHD_OPTION_UNESCAPE_CALLBACK.
*/
MHD_OPTION_UNESCAPE_CALLBACK = 16,
@@ -1370,7 +1584,7 @@
* of the buffer pointed to by the second argument in bytes.
* Note that the application must ensure that the buffer of the
* second argument remains allocated and unmodified while the
- * deamon is running.
+ * daemon is running.
*/
MHD_OPTION_DIGEST_AUTH_RANDOM = 17,
@@ -1389,7 +1603,7 @@
/**
* Memory pointer for the certificate (ca.pem) to be used by the
- * HTTPS daemon for client authentification.
+ * HTTPS daemon for client authentication.
* This option should be followed by a `const char *` argument.
*/
MHD_OPTION_HTTPS_MEM_TRUST = 20,
@@ -1436,7 +1650,7 @@
* If present and set to true, allow reusing address:port socket
* (by using SO_REUSEPORT on most platform, or platform-specific ways).
* If present and set to false, disallow reusing address:port socket
- * (does nothing on most plaform, but uses SO_EXCLUSIVEADDRUSE on Windows).
+ * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on Windows).
* This option must be followed by a `unsigned int` argument.
*/
MHD_OPTION_LISTENING_ADDRESS_REUSE = 25,
@@ -1470,23 +1684,84 @@
MHD_OPTION_LISTEN_BACKLOG_SIZE = 28,
/**
- * If set to 1 - be strict about the protocol (as opposed to as
- * tolerant as possible). Specifically, at the moment, this flag
- * causes MHD to reject HTTP 1.1 connections without a "Host" header.
- * This is required by the standard, but of course in violation of
- * the "be as liberal as possible in what you accept" norm. It is
- * recommended to set this to 1 if you are testing clients against
- * MHD, and 0 in production.
- * if set to -1 - be opposite to strict and be permissive about the
- * protocol, allowing slight deviations that are technically not
- * allowed by the RFC. Specifically, at the moment, this flag
- * causes MHD to allow spaces in header field names. This is
- * disallowed by the standard.
- * It is not recommended to set it to -1 on publicly available
- * servers as it may potentially lower level of protection.
+ * If set to 1 - be strict about the protocol. Use -1 to be
+ * as tolerant as possible.
+ *
+ * Specifically, at the moment, at 1 this flag
+ * causes MHD to reject HTTP 1.1 connections without a "Host" header,
+ * and to disallow spaces in the URL or (at -1) in HTTP header key strings.
+ *
+ * These are required by some versions of the standard, but of
+ * course in violation of the "be as liberal as possible in what you
+ * accept" norm. It is recommended to set this to 1 if you are
+ * testing clients against MHD, and 0 in production. This option
+ * should be followed by an `int` argument.
+ */
+ MHD_OPTION_STRICT_FOR_CLIENT = 29,
+
+ /**
+ * This should be a pointer to callback of type
+ * gnutls_psk_server_credentials_function that will be given to
+ * gnutls_psk_set_server_credentials_function. It is used to
+ * retrieve the shared key for a given username.
+ */
+ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER = 30,
+
+ /**
+ * Use a callback to determine which X.509 certificate should be
+ * used for a given HTTPS connection. This option should be
+ * followed by a argument of type `gnutls_certificate_retrieve_function3 *`.
+ * This option provides an
+ * alternative/extension to #MHD_OPTION_HTTPS_CERT_CALLBACK.
+ * You must use this version if you want to use OCSP stapling.
+ * Using this option requires GnuTLS 3.6.3 or higher.
+ */
+ MHD_OPTION_HTTPS_CERT_CALLBACK2 = 31,
+
+ /**
+ * Allows the application to disable certain sanity precautions
+ * in MHD. With these, the client can break the HTTP protocol,
+ * so this should never be used in production. The options are,
+ * however, useful for testing HTTP clients against "broken"
+ * server implementations.
+ * This argument must be followed by an "unsigned int", corresponding
+ * to an `enum MHD_DisableSanityCheck`.
+ */
+ MHD_OPTION_SERVER_INSANITY = 32,
+
+ /**
+ * If followed by value '1' informs MHD that SIGPIPE is suppressed or
+ * handled by application. Allows MHD to use network functions that could
+ * generate SIGPIPE, like `sendfile()`.
+ * Valid only for daemons without #MHD_USE_INTERNAL_POLLING_THREAD as
+ * MHD automatically suppresses SIGPIPE for threads started by MHD.
* This option should be followed by an `int` argument.
+ * @note Available since #MHD_VERSION 0x00097205
+ */
+ MHD_OPTION_SIGPIPE_HANDLED_BY_APP = 33,
+
+ /**
+ * If followed by 'int' with value '1' disables usage of ALPN for TLS
+ * connections even if supported by TLS library.
+ * Valid only for daemons with #MHD_USE_TLS.
+ * This option should be followed by an `int` argument.
+ * @note Available since #MHD_VERSION 0x00097207
+ */
+ MHD_OPTION_TLS_NO_ALPN = 34
+};
+
+
+/**
+ * Bitfield for the #MHD_OPTION_SERVER_INSANITY specifying
+ * which santiy checks should be disabled.
+ */
+enum MHD_DisableSanityCheck
+{
+ /**
+ * All sanity checks are enabled.
*/
- MHD_OPTION_STRICT_FOR_CLIENT = 29
+ MHD_DSC_SANE = 0
+
};
@@ -1530,7 +1805,8 @@
*/
MHD_RESPONSE_HEADER_KIND = 0,
#define MHD_RESPONSE_HEADER_KIND \
- _MHD_DEPR_IN_MACRO("Value MHD_RESPONSE_HEADER_KIND is deprecated and not used") \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_RESPONSE_HEADER_KIND is deprecated and not used") \
MHD_RESPONSE_HEADER_KIND
/**
@@ -1715,6 +1991,24 @@
/**
+ * I/O vector type. Provided for use with #MHD_create_response_from_iovec().
+ * @note Available since #MHD_VERSION 0x00097204
+ */
+struct MHD_IoVec
+{
+ /**
+ * The pointer to the memory region for I/O.
+ */
+ const void *iov_base;
+
+ /**
+ * The size in bytes of the memory region for I/O.
+ */
+ size_t iov_len;
+};
+
+
+/**
* Values of this enum are used to specify what
* information about a connection is desired.
* @ingroup request
@@ -1766,6 +2060,7 @@
/**
* Request the file descriptor for the connection socket.
+ * MHD sockets are always in non-blocking mode.
* No extra arguments should be passed.
* @ingroup request
*/
@@ -1803,7 +2098,7 @@
/**
* Values of this enum are used to specify what
- * information about a deamon is desired.
+ * information about a daemon is desired.
*/
enum MHD_DaemonInfoType
{
@@ -1826,6 +2121,8 @@
/**
* Request the file descriptor for the external epoll.
* No extra arguments should be passed.
+ * Waiting on epoll FD must not block longer than value
+ * returned by #MHD_get_timeout().
*/
MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY,
MHD_DAEMON_INFO_EPOLL_FD = MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY,
@@ -1845,7 +2142,15 @@
* Note: flags may differ from original 'flags' specified for
* daemon, especially if #MHD_USE_AUTO was set.
*/
- MHD_DAEMON_INFO_FLAGS
+ MHD_DAEMON_INFO_FLAGS,
+
+ /**
+ * Request the port number of daemon's listen socket.
+ * No extra arguments should be passed.
+ * Note: if port '0' was specified for #MHD_start_daemon(), returned
+ * value will be real port number.
+ */
+ MHD_DAEMON_INFO_BIND_PORT
};
@@ -1854,8 +2159,8 @@
* an error message and `abort()`.
*
* @param cls user specified value
- * @param file where the error occured
- * @param line where the error occured
+ * @param file where the error occurred
+ * @param line where the error occurred
* @param reason error detail, may be NULL
* @ingroup logging
*/
@@ -1873,10 +2178,10 @@
* @param addrlen length of @a addr
* @return #MHD_YES if connection is allowed, #MHD_NO if not
*/
-typedef int
-(*MHD_AcceptPolicyCallback) (void *cls,
- const struct sockaddr *addr,
- socklen_t addrlen);
+typedef enum MHD_Result
+(*MHD_AcceptPolicyCallback)(void *cls,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
/**
@@ -1901,10 +2206,10 @@
* part of #MHD_get_connection_values; very large POST
* data *will* be made available incrementally in
* @a upload_data)
- * @param upload_data_size set initially to the size of the
+ * @param[in,out] upload_data_size set initially to the size of the
* @a upload_data provided; the method must update this
* value to the number of bytes NOT processed;
- * @param con_cls pointer that the callback can set to some
+ * @param[in,out] con_cls pointer that the callback can set to some
* address and that will be preserved by MHD for future
* calls for this request; since the access handler may
* be called many times (i.e., for a PUT/POST operation
@@ -1915,18 +2220,18 @@
* can be set with the #MHD_OPTION_NOTIFY_COMPLETED).
* Initially, `*con_cls` will be NULL.
* @return #MHD_YES if the connection was handled successfully,
- * #MHD_NO if the socket must be closed due to a serios
+ * #MHD_NO if the socket must be closed due to a serious
* error while handling the request
*/
-typedef int
-(*MHD_AccessHandlerCallback) (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **con_cls);
+typedef enum MHD_Result
+(*MHD_AccessHandlerCallback)(void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls);
/**
@@ -1947,6 +2252,7 @@
void **con_cls,
enum MHD_RequestTerminationCode toe);
+
/**
* Signature of the callback used by MHD to notify the
* application about started/stopped connections
@@ -1988,11 +2294,38 @@
* #MHD_NO to abort the iteration
* @ingroup request
*/
-typedef int
-(*MHD_KeyValueIterator) (void *cls,
+typedef enum MHD_Result
+(*MHD_KeyValueIterator)(void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *value);
+
+
+/**
+ * Iterator over key-value pairs with size parameters.
+ * This iterator can be used to iterate over all of
+ * the cookies, headers, or POST-data fields of a
+ * request, and also to iterate over the headers that
+ * have been added to a response.
+ * @note Available since #MHD_VERSION 0x00096303
+ *
+ * @param cls closure
+ * @param kind kind of the header we are looking at
+ * @param key key for the value, can be an empty string
+ * @param value corresponding value, can be NULL
+ * @param value_size number of bytes in @a value, NEW since #MHD_VERSION 0x00096301;
+ * for C-strings, the length excludes the 0-terminator
+ * @return #MHD_YES to continue iterating,
+ * #MHD_NO to abort the iteration
+ * @ingroup request
+ */
+typedef enum MHD_Result
+(*MHD_KeyValueIteratorN)(void *cls,
enum MHD_ValueKind kind,
const char *key,
- const char *value);
+ size_t key_size,
+ const char *value,
+ size_t value_size);
/**
@@ -2078,16 +2411,16 @@
* @return #MHD_YES to continue iterating,
* #MHD_NO to abort the iteration
*/
-typedef int
-(*MHD_PostDataIterator) (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *filename,
- const char *content_type,
- const char *transfer_encoding,
- const char *data,
- uint64_t off,
- size_t size);
+typedef enum MHD_Result
+(*MHD_PostDataIterator)(void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size);
/* **************** Daemon handling functions ***************** */
@@ -2095,7 +2428,11 @@
* Start a webserver on the given port.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to (in host byte order)
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -2110,10 +2447,10 @@
*/
_MHD_EXTERN struct MHD_Daemon *
MHD_start_daemon_va (unsigned int flags,
- uint16_t port,
- MHD_AcceptPolicyCallback apc, void *apc_cls,
- MHD_AccessHandlerCallback dh, void *dh_cls,
- va_list ap);
+ uint16_t port,
+ MHD_AcceptPolicyCallback apc, void *apc_cls,
+ MHD_AccessHandlerCallback dh, void *dh_cls,
+ va_list ap);
/**
@@ -2121,7 +2458,11 @@
* #MHD_start_daemon_va.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if MHD_OPTION_SOCK_ADDR or
+ * MHD_OPTION_LISTEN_SOCKET is provided
+ * or MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -2134,10 +2475,10 @@
*/
_MHD_EXTERN struct MHD_Daemon *
MHD_start_daemon (unsigned int flags,
- uint16_t port,
- MHD_AcceptPolicyCallback apc, void *apc_cls,
- MHD_AccessHandlerCallback dh, void *dh_cls,
- ...);
+ uint16_t port,
+ MHD_AcceptPolicyCallback apc, void *apc_cls,
+ MHD_AccessHandlerCallback dh, void *dh_cls,
+ ...);
/**
@@ -2189,8 +2530,6 @@
* this call and must no longer be used directly by the application
* afterwards.
*
- * Per-IP connection limits are ignored when using this API.
- *
* @param daemon daemon that manages the connection
* @param client_socket socket to manage (MHD will expect
* to receive an HTTP request from this socket next).
@@ -2202,11 +2541,11 @@
* set to indicate further details about the error.
* @ingroup specialized
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_add_connection (struct MHD_Daemon *daemon,
- MHD_socket client_socket,
- const struct sockaddr *addr,
- socklen_t addrlen);
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
/**
@@ -2217,9 +2556,11 @@
* to be platform's default.
*
* This function should only be called in when MHD is configured to
- * use external select with @code{select()} or with @code{epoll()}.
- * In the latter case, it will only add the single @code{epoll()} file
+ * use external select with 'select()' or with 'epoll'.
+ * In the latter case, it will only add the single 'epoll()' file
* descriptor used by MHD to the sets.
+ * It's necessary to use #MHD_get_timeout() in combination with
+ * this function.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -2236,12 +2577,12 @@
* fit fd_set.
* @ingroup event
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_get_fdset (struct MHD_Daemon *daemon,
fd_set *read_fd_set,
fd_set *write_fd_set,
- fd_set *except_fd_set,
- MHD_socket *max_fd);
+ fd_set *except_fd_set,
+ MHD_socket *max_fd);
/**
@@ -2254,9 +2595,11 @@
* larger/smaller than platform's default fd_sets.
*
* This function should only be called in when MHD is configured to
- * use external select with @code{select()} or with @code{epoll()}.
- * In the latter case, it will only add the single @code{epoll()} file
+ * use external select with 'select()' or with 'epoll'.
+ * In the latter case, it will only add the single 'epoll' file
* descriptor used by MHD to the sets.
+ * It's necessary to use #MHD_get_timeout() in combination with
+ * this function.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -2274,13 +2617,13 @@
* fit fd_set.
* @ingroup event
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_get_fdset2 (struct MHD_Daemon *daemon,
- fd_set *read_fd_set,
- fd_set *write_fd_set,
- fd_set *except_fd_set,
- MHD_socket *max_fd,
- unsigned int fd_setsize);
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize);
/**
@@ -2289,6 +2632,8 @@
* daemon FDs in fd_sets, call FD_ZERO for each fd_set
* before calling this function. Size of fd_set is
* determined by current value of FD_SETSIZE.
+ * It's necessary to use #MHD_get_timeout() in combination with
+ * this function.
*
* This function could be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -2306,32 +2651,38 @@
* @ingroup event
*/
#define MHD_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set,max_fd) \
- MHD_get_fdset2((daemon),(read_fd_set),(write_fd_set),(except_fd_set),(max_fd),FD_SETSIZE)
+ MHD_get_fdset2 ((daemon),(read_fd_set),(write_fd_set),(except_fd_set), \
+ (max_fd),FD_SETSIZE)
/**
- * Obtain timeout value for `select()` for this daemon (only needed if
- * connection timeout is used). The returned value is how many milliseconds
- * `select()` or `poll()` should at most block, not the timeout value set for
- * connections. This function MUST NOT be called if MHD is running with
- * #MHD_USE_THREAD_PER_CONNECTION.
+ * Obtain timeout value for polling function for this daemon.
+ * This function set value to amount of milliseconds for which polling
+ * function (`select()` or `poll()`) should at most block, not the
+ * timeout value set for connections.
+ * It is important to always use this function, even if connection
+ * timeout is not set, as in some cases MHD may already have more
+ * data to process on next turn (data pending in TLS buffers,
+ * connections are already ready with epoll etc.) and returned timeout
+ * will be zero.
*
* @param daemon daemon to query for timeout
* @param timeout set to the timeout (in milliseconds)
* @return #MHD_YES on success, #MHD_NO if timeouts are
* not used (or no connections exist that would
- * necessiate the use of a timeout right now).
+ * necessitate the use of a timeout right now).
* @ingroup event
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_get_timeout (struct MHD_Daemon *daemon,
- MHD_UNSIGNED_LONG_LONG *timeout);
+ MHD_UNSIGNED_LONG_LONG *timeout);
/**
* Run webserver operations (without blocking unless in client
* callbacks). This method should be called by clients in combination
- * with #MHD_get_fdset if the client-controlled select method is used.
+ * with #MHD_get_fdset if the client-controlled select method is used and
+ * #MHD_get_timeout().
*
* This function is a convenience method, which is useful if the
* fd_sets from #MHD_get_fdset were not directly passed to `select()`;
@@ -2347,14 +2698,47 @@
* options for this call.
* @ingroup event
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_run (struct MHD_Daemon *daemon);
/**
+ * Run websever operation with possible blocking.
+ * This function do the following: waits for any network event not more than
+ * specified number of milliseconds, processes all incoming and outgoing
+ * data, processes new connections, processes any timed-out connection, and
+ * do other things required to run webserver.
+ * Once all connections are processed, function returns.
+ * This function is useful for quick and simple webserver implementation if
+ * application needs to run a single thread only and does not have any other
+ * network activity.
+ * @param daemon the daemon to run
+ * @param millisec the maximum time in milliseconds to wait for network and
+ * other events. Note: there is no guarantee that function
+ * blocks for specified amount of time. The real processing
+ * time can be shorter (if some data comes earlier) or
+ * longer (if data processing requires more time, especially
+ * in the user callbacks).
+ * If set to '0' then function does not block and processes
+ * only already available data (if any).
+ * If set to '-1' then function waits for events
+ * indefinitely (blocks until next network activity).
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or some serious
+ * unrecoverable error occurs.
+ * @note Available since #MHD_VERSION 0x00097206
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_run_wait (struct MHD_Daemon *daemon,
+ int32_t millisec);
+
+
+/**
* Run webserver operations. This method should be called by clients
- * in combination with #MHD_get_fdset if the client-controlled select
- * method is used.
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
*
* You can use this function instead of #MHD_run if you called
* `select()` on the result from #MHD_get_fdset. File descriptors in
@@ -2373,13 +2757,11 @@
* @return #MHD_NO on serious errors, #MHD_YES on success
* @ingroup event
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_run_from_select (struct MHD_Daemon *daemon,
- const fd_set *read_fd_set,
- const fd_set *write_fd_set,
- const fd_set *except_fd_set);
-
-
+ const fd_set *read_fd_set,
+ const fd_set *write_fd_set,
+ const fd_set *except_fd_set);
/* **************** Connection handling functions ***************** */
@@ -2392,7 +2774,8 @@
* @param iterator callback to call on each header;
* maybe NULL (then just count headers)
* @param iterator_cls extra argument to @a iterator
- * @return number of entries iterated over
+ * @return number of entries iterated over,
+ * -1 if connection is NULL.
* @ingroup request
*/
_MHD_EXTERN int
@@ -2403,6 +2786,26 @@
/**
+ * Get all of the headers from the request.
+ *
+ * @param connection connection to get values from
+ * @param kind types of values to iterate over, can be a bitmask
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over,
+ * -1 if connection is NULL.
+ * @note Available since #MHD_VERSION 0x00096400
+ * @ingroup request
+ */
+_MHD_EXTERN int
+MHD_get_connection_values_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ MHD_KeyValueIteratorN iterator,
+ void *iterator_cls);
+
+
+/**
* This function can be used to add an entry to the HTTP headers of a
* connection (so that the #MHD_get_connection_values function will
* return them -- and the `struct MHD_PostProcessor` will also see
@@ -2428,11 +2831,46 @@
* #MHD_YES on success
* @ingroup request
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_set_connection_value (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
- const char *value);
+ const char *value);
+
+
+/**
+ * This function can be used to add an arbitrary entry to connection.
+ * This function could add entry with binary zero, which is allowed
+ * for #MHD_GET_ARGUMENT_KIND. For other kind on entries it is
+ * recommended to use #MHD_set_connection_value.
+ *
+ * This function MUST only be called from within the
+ * #MHD_AccessHandlerCallback (otherwise, access maybe improperly
+ * synchronized). Furthermore, the client must guarantee that the key
+ * and value arguments are 0-terminated strings that are NOT freed
+ * until the connection is closed. (The easiest way to do this is by
+ * passing only arguments to permanently allocated strings.).
+ *
+ * @param connection the connection for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value, must be zero-terminated
+ * @param key_size number of bytes in @a key (excluding 0-terminator)
+ * @param value the value itself, must be zero-terminated
+ * @param value_size number of bytes in @a value (excluding 0-terminator)
+ * @return #MHD_NO if the operation could not be
+ * performed due to insufficient memory;
+ * #MHD_YES on success
+ * @note Available since #MHD_VERSION 0x00096400
+ * @ingroup request
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_set_connection_value_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char *value,
+ size_t value_size);
/**
@@ -2480,8 +2918,36 @@
*/
_MHD_EXTERN const char *
MHD_lookup_connection_value (struct MHD_Connection *connection,
- enum MHD_ValueKind kind,
- const char *key);
+ enum MHD_ValueKind kind,
+ const char *key);
+
+
+/**
+ * Get a particular header value. If multiple
+ * values match the kind, return any one of them.
+ * @note Since MHD_VERSION 0x00096304
+ *
+ * @param connection connection to get values from
+ * @param kind what kind of value are we looking for
+ * @param key the header to look for, NULL to lookup 'trailing' value without a key
+ * @param key_size the length of @a key in bytes
+ * @param[out] value_ptr the pointer to variable, which will be set to found value,
+ * will not be updated if key not found,
+ * could be NULL to just check for presence of @a key
+ * @param[out] value_size_ptr the pointer variable, which will set to found value,
+ * will not be updated if key not found,
+ * could be NULL
+ * @return #MHD_YES if key is found,
+ * #MHD_NO otherwise.
+ * @ingroup request
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_lookup_connection_value_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char **value_ptr,
+ size_t *value_size_ptr);
/**
@@ -2495,10 +2961,10 @@
* #MHD_YES on success or if message has been queued
* @ingroup response
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_queue_response (struct MHD_Connection *connection,
unsigned int status_code,
- struct MHD_Response *response);
+ struct MHD_Response *response);
/**
@@ -2537,10 +3003,10 @@
* result in undefined behavior.
*
* If you are using this function in ``external'' select mode, you must
- * make sure to run #MHD_run() afterwards (before again calling
- * #MHD_get_fdset(), as otherwise the change may not be reflected in
- * the set returned by #MHD_get_fdset() and you may end up with a
- * connection that is stuck until the next network activity.
+ * make sure to run #MHD_run() and #MHD_get_timeout() afterwards (before
+ * again calling #MHD_get_fdset()), as otherwise the change may not be
+ * reflected in the set returned by #MHD_get_fdset() and you may end up
+ * with a connection that is stuck until the next network activity.
*
* @param connection the connection to resume
*/
@@ -2565,8 +3031,26 @@
* Only respond in conservative HTTP 1.0-mode. In particular,
* do not (automatically) sent "Connection" headers and always
* close the connection after generating the response.
+ * By default, MHD will respond using the same HTTP version which
+ * was set in the request. You can also set the
+ * #MHD_RF_HTTP_VERSION_1_0_RESPONSE flag to force version 1.0
+ * in the response.
+ */
+ MHD_RF_HTTP_VERSION_1_0_ONLY = 1,
+
+ /**
+ * Only respond in HTTP 1.0-mode. Contrary to the
+ * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will
+ * always be set to 1.0 and "Connection" headers are still supported.
*/
- MHD_RF_HTTP_VERSION_1_0_ONLY = 1
+ MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2,
+
+ /**
+ * Disable sanity check preventing clients from manually
+ * setting the HTTP content length option.
+ */
+ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH = 4
+
};
@@ -2591,7 +3075,7 @@
* @param ... #MHD_RO_END terminated list of options
* @return #MHD_YES on success, #MHD_NO on error
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_set_response_options (struct MHD_Response *response,
enum MHD_ResponseFlags flags,
...);
@@ -2615,9 +3099,9 @@
*/
_MHD_EXTERN struct MHD_Response *
MHD_create_response_from_callback (uint64_t size,
- size_t block_size,
- MHD_ContentReaderCallback crc, void *crc_cls,
- MHD_ContentReaderFreeCallback crfc);
+ size_t block_size,
+ MHD_ContentReaderCallback crc, void *crc_cls,
+ MHD_ContentReaderFreeCallback crfc);
/**
@@ -2634,12 +3118,13 @@
* @deprecated use #MHD_create_response_from_buffer instead
* @ingroup response
*/
-_MHD_DEPR_FUNC("MHD_create_response_from_data() is deprecated, use MHD_create_response_from_buffer()") \
-_MHD_EXTERN struct MHD_Response *
+_MHD_DEPR_FUNC (
+ "MHD_create_response_from_data() is deprecated, use MHD_create_response_from_buffer()") \
+ _MHD_EXTERN struct MHD_Response *
MHD_create_response_from_data (size_t size,
- void *data,
- int must_free,
- int must_copy);
+ void *data,
+ int must_free,
+ int must_copy);
/**
@@ -2690,8 +3175,26 @@
*/
_MHD_EXTERN struct MHD_Response *
MHD_create_response_from_buffer (size_t size,
- void *buffer,
- enum MHD_ResponseMemoryMode mode);
+ void *buffer,
+ enum MHD_ResponseMemoryMode mode);
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
+ * @param buffer size bytes containing the response's data portion
+ * @param crfc function to call to free the @a buffer
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @note Available since #MHD_VERSION 0x00096000
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_buffer_with_free_callback (size_t size,
+ void *buffer,
+ MHD_ContentReaderFreeCallback
+ crfc);
/**
@@ -2707,7 +3210,22 @@
*/
_MHD_EXTERN struct MHD_Response *
MHD_create_response_from_fd (size_t size,
- int fd);
+ int fd);
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used ONLY ONCE.
+ *
+ * @param fd file descriptor referring to a read-end of a pipe with the
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @note Available since #MHD_VERSION 0x00097102
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_pipe (int fd);
/**
@@ -2744,18 +3262,20 @@
* @return NULL on error (i.e. invalid arguments, out of memory)
* @ingroup response
*/
-_MHD_DEPR_FUNC("Function MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \
-_MHD_EXTERN struct MHD_Response *
+_MHD_DEPR_FUNC (
+ "Function MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \
+ _MHD_EXTERN struct MHD_Response *
MHD_create_response_from_fd_at_offset (size_t size,
int fd,
off_t offset);
-#if !defined(_MHD_NO_DEPR_IN_MACRO) || defined(_MHD_NO_DEPR_FUNC)
+#if ! defined(_MHD_NO_DEPR_IN_MACRO) || defined(_MHD_NO_DEPR_FUNC)
/* Substitute MHD_create_response_from_fd_at_offset64() instead of MHD_create_response_from_fd_at_offset()
to minimize potential problems with different off_t sizes */
#define MHD_create_response_from_fd_at_offset(size,fd,offset) \
- _MHD_DEPR_IN_MACRO("Usage of MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \
- MHD_create_response_from_fd_at_offset64((size),(fd),(offset))
+ _MHD_DEPR_IN_MACRO ( \
+ "Usage of MHD_create_response_from_fd_at_offset() is deprecated, use MHD_create_response_from_fd_at_offset64()") \
+ MHD_create_response_from_fd_at_offset64 ((size),(fd),(offset))
#endif /* !_MHD_NO_DEPR_IN_MACRO || _MHD_NO_DEPR_FUNC */
@@ -2782,6 +3302,28 @@
/**
+ * Create a response object from an array of memory buffers.
+ * The response object can be extended with header information and then be used
+ * any number of times.
+ *
+ * @param iov the array for response data buffers, an internal copy of this
+ * will be made
+ * @param iovcnt the number of elements in @a iov
+ * @param free_cb the callback to clean up any data associated with @a iov when
+ * the response is destroyed.
+ * @param cls the argument passed to @a free_cb
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @note Available since #MHD_VERSION 0x00097204
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_iovec (const struct MHD_IoVec *iov,
+ unsigned int iovcnt,
+ MHD_ContentReaderFreeCallback free_cb,
+ void *cls);
+
+
+/**
* Enumeration for actions MHD should perform on the underlying socket
* of the upgrade. This API is not finalized, and in particular
* the final set of actions is yet to be decided. This is just an
@@ -2795,7 +3337,17 @@
*
* Takes no extra arguments.
*/
- MHD_UPGRADE_ACTION_CLOSE = 0
+ MHD_UPGRADE_ACTION_CLOSE = 0,
+
+ /**
+ * Enable CORKing on the underlying socket.
+ */
+ MHD_UPGRADE_ACTION_CORK_ON = 1,
+
+ /**
+ * Disable CORKing on the underlying socket.
+ */
+ MHD_UPGRADE_ACTION_CORK_OFF = 2
};
@@ -2820,7 +3372,7 @@
* @param ... arguments to the action (depends on the action)
* @return #MHD_NO on error, #MHD_YES on success
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
enum MHD_UpgradeAction action,
...);
@@ -2914,14 +3466,14 @@
*/
_MHD_EXTERN struct MHD_Response *
MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
- void *upgrade_handler_cls);
+ void *upgrade_handler_cls);
/**
* Destroy a response object and associated resources. Note that
* libmicrohttpd may keep some of the resources around if the response
* is still in the queue for some clients, so the memory may not
- * necessarily be freed immediatley.
+ * necessarily be freed immediately.
*
* @param response response to destroy
* @ingroup response
@@ -2940,10 +3492,10 @@
* or out of memory
* @ingroup response
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_add_response_header (struct MHD_Response *response,
const char *header,
- const char *content);
+ const char *content);
/**
@@ -2955,10 +3507,10 @@
* @return #MHD_NO on error (i.e. invalid footer or content format).
* @ingroup response
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_add_response_footer (struct MHD_Response *response,
const char *footer,
- const char *content);
+ const char *content);
/**
@@ -2970,10 +3522,10 @@
* @return #MHD_NO on error (no such header known)
* @ingroup response
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_del_response_header (struct MHD_Response *response,
const char *header,
- const char *content);
+ const char *content);
/**
@@ -2988,7 +3540,8 @@
*/
_MHD_EXTERN int
MHD_get_response_headers (struct MHD_Response *response,
- MHD_KeyValueIterator iterator, void *iterator_cls);
+ MHD_KeyValueIterator iterator,
+ void *iterator_cls);
/**
@@ -3001,7 +3554,7 @@
*/
_MHD_EXTERN const char *
MHD_get_response_header (struct MHD_Response *response,
- const char *key);
+ const char *key);
/* ********************** PostProcessor functions ********************** */
@@ -3033,8 +3586,8 @@
*/
_MHD_EXTERN struct MHD_PostProcessor *
MHD_create_post_processor (struct MHD_Connection *connection,
- size_t buffer_size,
- MHD_PostDataIterator iter, void *iter_cls);
+ size_t buffer_size,
+ MHD_PostDataIterator iter, void *iter_cls);
/**
@@ -3050,9 +3603,10 @@
* (out-of-memory, iterator aborted, parse error)
* @ingroup request
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_post_process (struct MHD_PostProcessor *pp,
- const char *post_data, size_t post_data_len);
+ const char *post_data,
+ size_t post_data_len);
/**
@@ -3065,7 +3619,7 @@
* value of this function
* @ingroup request
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_destroy_post_processor (struct MHD_PostProcessor *pp);
@@ -3085,7 +3639,7 @@
*
* @param connection The MHD connection structure
* @return NULL if no username could be found, a pointer
- * to the username if found
+ * to the username if found, free using #MHD_free().
* @ingroup authentication
*/
_MHD_EXTERN char *
@@ -3093,28 +3647,175 @@
/**
- * Authenticates the authorization header sent by the client
+ * Free the memory given by @a ptr. Calls "free(ptr)". This function
+ * should be used to free the username returned by
+ * #MHD_digest_auth_get_username().
+ * @note Available since #MHD_VERSION 0x00095600
+ *
+ * @param ptr pointer to free.
+ */
+_MHD_EXTERN void
+MHD_free (void *ptr);
+
+
+/**
+ * Which digest algorithm should MHD use for HTTP digest authentication?
+ */
+enum MHD_DigestAuthAlgorithm
+{
+
+ /**
+ * MHD should pick (currently defaults to SHA-256).
+ */
+ MHD_DIGEST_ALG_AUTO = 0,
+
+ /**
+ * Force use of MD5.
+ */
+ MHD_DIGEST_ALG_MD5,
+
+ /**
+ * Force use of SHA-256.
+ */
+ MHD_DIGEST_ALG_SHA256
+
+};
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param password The password used in the authentication
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @param algo digest algorithms allowed for verification
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @note Available since #MHD_VERSION 0x00096200
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const char *password,
+ unsigned int nonce_timeout,
+ enum MHD_DigestAuthAlgorithm algo);
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ * Uses #MHD_DIGEST_ALG_MD5 (for now, for backwards-compatibility).
+ * Note that this MAY change to #MHD_DIGEST_ALG_AUTO in the future.
+ * If you want to be sure you get MD5, use #MHD_digest_auth_check2()
+ * and specify MD5 explicitly.
*
* @param connection The MHD connection structure
* @param realm The realm presented to the client
* @param username The username needs to be authenticated
* @param password The password used in the authentication
* @param nonce_timeout The amount of time for a nonce to be
- * invalid in seconds
+ * invalid in seconds
* @return #MHD_YES if authenticated, #MHD_NO if not,
- * #MHD_INVALID_NONCE if nonce is invalid
+ * #MHD_INVALID_NONCE if nonce is invalid
* @ingroup authentication
+ * @deprecated use MHD_digest_auth_check2()
*/
_MHD_EXTERN int
MHD_digest_auth_check (struct MHD_Connection *connection,
- const char *realm,
- const char *username,
- const char *password,
- unsigned int nonce_timeout);
+ const char *realm,
+ const char *username,
+ const char *password,
+ unsigned int nonce_timeout);
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param digest An `unsigned char *' pointer to the binary MD5 sum
+ * for the precalculated hash value "username:realm:password"
+ * of @a digest_size bytes
+ * @param digest_size number of bytes in @a digest (size must match @a algo!)
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @param algo digest algorithms allowed for verification
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @note Available since #MHD_VERSION 0x00096200
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check_digest2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const uint8_t *digest,
+ size_t digest_size,
+ unsigned int nonce_timeout,
+ enum MHD_DigestAuthAlgorithm algo);
+
+
+/**
+ * Authenticates the authorization header sent by the client
+ * Uses #MHD_DIGEST_ALG_MD5 (required, as @a digest is of fixed
+ * size).
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param digest An `unsigned char *' pointer to the binary hash
+ * for the precalculated hash value "username:realm:password";
+ * length must be #MHD_MD5_DIGEST_SIZE bytes
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @note Available since #MHD_VERSION 0x00096000
+ * @ingroup authentication
+ * @deprecated use #MHD_digest_auth_check_digest2()
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check_digest (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const uint8_t digest[MHD_MD5_DIGEST_SIZE],
+ unsigned int nonce_timeout);
+
+
+/**
+ * Queues a response to request authentication from the client
+ *
+ * @param connection The MHD connection structure
+ * @param realm the realm presented to the client
+ * @param opaque string to user for opaque value
+ * @param response reply to send; should contain the "access denied"
+ * body; note that this function will set the "WWW Authenticate"
+ * header and that the caller should not do this
+ * @param signal_stale #MHD_YES if the nonce is invalid to add
+ * 'stale=true' to the authentication header
+ * @param algo digest algorithm to use
+ * @return #MHD_YES on success, #MHD_NO otherwise
+ * @note Available since #MHD_VERSION 0x00096200
+ * @ingroup authentication
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_queue_auth_fail_response2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *opaque,
+ struct MHD_Response *response,
+ int signal_stale,
+ enum MHD_DigestAuthAlgorithm algo);
/**
* Queues a response to request authentication from the client
+ * For now uses MD5 (for backwards-compatibility). Still, if you
+ * need to be sure, use #MHD_queue_fail_auth_response2().
*
* @param connection The MHD connection structure
* @param realm The realm presented to the client
@@ -3123,30 +3824,31 @@
* body; note that this function will set the "WWW Authenticate"
* header and that the caller should not do this
* @param signal_stale #MHD_YES if the nonce is invalid to add
- * 'stale=true' to the authentication header
+ * 'stale=true' to the authentication header
* @return #MHD_YES on success, #MHD_NO otherwise
* @ingroup authentication
+ * @deprecated use MHD_queue_auth_fail_response2()
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_queue_auth_fail_response (struct MHD_Connection *connection,
- const char *realm,
- const char *opaque,
- struct MHD_Response *response,
- int signal_stale);
+ const char *realm,
+ const char *opaque,
+ struct MHD_Response *response,
+ int signal_stale);
/**
* Get the username and password from the basic authorization header sent by the client
*
* @param connection The MHD connection structure
- * @param password a pointer for the password
+ * @param[out] password a pointer for the password, free using #MHD_free().
* @return NULL if no username could be found, a pointer
- * to the username if found
+ * to the username if found, free using #MHD_free().
* @ingroup authentication
*/
_MHD_EXTERN char *
MHD_basic_auth_get_username_password (struct MHD_Connection *connection,
- char** password);
+ char**password);
/**
@@ -3161,10 +3863,10 @@
* @return #MHD_YES on success, #MHD_NO otherwise
* @ingroup authentication
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection,
- const char *realm,
- struct MHD_Response *response);
+ const char *realm,
+ struct MHD_Response *response);
/* ********************** generic query functions ********************** */
@@ -3181,8 +3883,8 @@
*/
_MHD_EXTERN const union MHD_ConnectionInfo *
MHD_get_connection_info (struct MHD_Connection *connection,
- enum MHD_ConnectionInfoType info_type,
- ...);
+ enum MHD_ConnectionInfoType info_type,
+ ...);
/**
@@ -3213,10 +3915,10 @@
* @return #MHD_YES on success, #MHD_NO if setting the option failed
* @ingroup specialized
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_set_connection_option (struct MHD_Connection *connection,
- enum MHD_CONNECTION_OPTION option,
- ...);
+ enum MHD_CONNECTION_OPTION option,
+ ...);
/**
@@ -3242,6 +3944,11 @@
MHD_socket listen_fd;
/**
+ * Bind port number, returned for #MHD_DAEMON_INFO_BIND_PORT.
+ */
+ uint16_t port;
+
+ /**
* epoll FD, returned for #MHD_DAEMON_INFO_EPOLL_FD.
*/
int epoll_fd;
@@ -3274,8 +3981,8 @@
*/
_MHD_EXTERN const union MHD_DaemonInfo *
MHD_get_daemon_info (struct MHD_Daemon *daemon,
- enum MHD_DaemonInfoType info_type,
- ...);
+ enum MHD_DaemonInfoType info_type,
+ ...);
/**
@@ -3427,7 +4134,38 @@
* It's always safe to use same file FD in multiple responses if MHD
* is run in any single thread mode.
*/
- MHD_FEATURE_RESPONSES_SHARED_FD = 18
+ MHD_FEATURE_RESPONSES_SHARED_FD = 18,
+
+ /**
+ * Get whether MHD support automatic detection of bind port number.
+ * @sa #MHD_DAEMON_INFO_BIND_PORT
+ */
+ MHD_FEATURE_AUTODETECT_BIND_PORT = 19,
+
+ /**
+ * Get whether MHD support SIGPIPE suppression.
+ * If SIGPIPE suppression is not supported, application must handle
+ * SIGPIPE signal by itself.
+ */
+ MHD_FEATURE_AUTOSUPPRESS_SIGPIPE = 20,
+
+ /**
+ * Get whether MHD use system's sendfile() function to send
+ * file-FD based responses over non-TLS connections.
+ * @note Since v0.9.56
+ */
+ MHD_FEATURE_SENDFILE = 21,
+
+ /**
+ * Get whether MHD supports threads.
+ */
+ MHD_FEATURE_THREADS = 22,
+
+ /**
+ * Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK2 is
+ * supported.
+ */
+ MHD_FEATURE_HTTPS_CERT_CALLBACK2 = 23
};
@@ -3442,7 +4180,7 @@
* feature is not supported or feature is unknown.
* @ingroup specialized
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_is_feature_supported (enum MHD_FEATURE feature);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/microhttpd2.h
^
|
@@ -0,0 +1,4250 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2006-2018 Christian Grothoff, Karlson2k (Evgeny Grin)
+ (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * Just includes the NEW definitions for the NG-API.
+ * Note that we do not indicate which of the OLD APIs
+ * simply need to be kept vs. deprecated.
+ *
+ *
+ * The goal is to provide a basis for discussion!
+ * Little of this is implemented yet.
+ *
+ * Main goals:
+ * - simplify application callbacks by splitting header/upload/post
+ * functionality currently provided by calling the same
+ * MHD_AccessHandlerCallback 3+ times into separate callbacks.
+ * - keep the API very simple for simple requests, but allow
+ * more complex logic to be incrementally introduced
+ * (via new struct MHD_Action construction)
+ * - avoid repeated scans for URL matches via the new
+ * struct MHD_Action construction
+ * - provide default logarithmic implementation of URL scan
+ * => reduce strcmp(url) from >= 3n operations to "log n"
+ * per request.
+ * - better types, in particular avoid varargs for options
+ * - make it harder to pass inconsistent options
+ * - combine options and flags into more uniform API (at least
+ * exterally!)
+ * - simplify API use by using sane defaults (benefiting from
+ * breaking backwards compatibility) and making all options
+ * really optional, and where applicable avoid having options
+ * where the default works if nothing is specified
+ * - simplify API by moving rarely used http_version into
+ * MHD_request_get_information()
+ * - avoid 'int' for MHD_YES/MHD_NO by introducing `enum MHD_Bool`
+ * - improve terminology by eliminating confusion between
+ * 'request' and 'connection'
+ * - prepare API for having multiple TLS backends
+ * - use more consistent prefixes for related functions
+ * by using MHD_subject_verb_object naming convention, also
+ * at the same time avoid symbol conflict with legacy names
+ * (so we can have one binary implementing old and new
+ * library API at the same time via compatibility layer).
+ * - make it impossible to queue a response at the wrong time
+ * - make it impossible to suspend a connection/request at the
+ * wrong time (improves thread-safety)
+ * - make it clear which response status codes are "properly"
+ * supported (include the descriptive string) by using an enum;
+ * - simplify API for common-case of one-shot responses by
+ * eliminating need for destroy response in most cases;
+ *
+ * TODO:
+ * - varargs in upgrade is still there and ugly (and not even used!)
+ * - migrate event loop apis (get fdset, timeout, MHD_run(), etc.)
+ */
+#ifndef MICROHTTPD2_H
+#define MICROHTTPD2_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+/* While we generally would like users to use a configure-driven
+ build process which detects which headers are present and
+ hence works on any platform, we use "standard" includes here
+ to build out-of-the-box for beginning users on common systems.
+
+ If generic headers don't work on your platform, include headers
+ which define 'va_list', 'size_t', 'ssize_t', 'intptr_t',
+ 'uint16_t', 'uint32_t', 'uint64_t', 'off_t', 'struct sockaddr',
+ 'socklen_t', 'fd_set' and "#define MHD_PLATFORM_H" before
+ including "microhttpd.h". Then the following "standard"
+ includes won't be used (which might be a good idea, especially
+ on platforms where they do not exist).
+ */
+#ifndef MHD_PLATFORM_H
+#include <stdarg.h>
+#include <stdint.h>
+#include <sys/types.h>
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+#include <ws2tcpip.h>
+#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
+#define _SSIZE_T_DEFINED
+typedef intptr_t ssize_t;
+#endif /* !_SSIZE_T_DEFINED */
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#endif
+#endif
+
+#if defined(__CYGWIN__) && ! defined(_SYS_TYPES_FD_SET)
+/* Do not define __USE_W32_SOCKETS under Cygwin! */
+#error Cygwin with winsock fd_set is not supported
+#endif
+
+/**
+ * Current version of the library.
+ * 0x01093001 = 1.9.30-1.
+ */
+#define MHD_VERSION 0x01000000
+
+
+/**
+ * Representation of 'bool' in the public API as stdbool.h may not
+ * always be available.
+ */
+enum MHD_Bool
+{
+
+ /**
+ * MHD-internal return code for "NO".
+ */
+ MHD_NO = 0,
+
+ /**
+ * MHD-internal return code for "YES". All non-zero values
+ * will be interpreted as "YES", but MHD will only ever
+ * return #MHD_YES or #MHD_NO.
+ */
+ MHD_YES = 1
+};
+
+
+/**
+ * Constant used to indicate unknown size (use when
+ * creating a response).
+ */
+#ifdef UINT64_MAX
+#define MHD_SIZE_UNKNOWN UINT64_MAX
+#else
+#define MHD_SIZE_UNKNOWN ((uint64_t) -1LL)
+#endif
+
+#ifdef SIZE_MAX
+#define MHD_CONTENT_READER_END_OF_STREAM SIZE_MAX
+#define MHD_CONTENT_READER_END_WITH_ERROR (SIZE_MAX - 1)
+#else
+#define MHD_CONTENT_READER_END_OF_STREAM ((size_t) -1LL)
+#define MHD_CONTENT_READER_END_WITH_ERROR (((size_t) -1LL) - 1)
+#endif
+
+#ifndef _MHD_EXTERN
+#if defined(_WIN32) && defined(MHD_W32LIB)
+#define _MHD_EXTERN extern
+#elif defined (_WIN32) && defined(MHD_W32DLL)
+/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */
+#define _MHD_EXTERN __declspec(dllimport)
+#else
+#define _MHD_EXTERN extern
+#endif
+#endif
+
+#ifndef MHD_SOCKET_DEFINED
+/**
+ * MHD_socket is type for socket FDs
+ */
+#if ! defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
+#define MHD_POSIX_SOCKETS 1
+typedef int MHD_socket;
+#define MHD_INVALID_SOCKET (-1)
+#else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
+#define MHD_WINSOCK_SOCKETS 1
+#include <winsock2.h>
+typedef SOCKET MHD_socket;
+#define MHD_INVALID_SOCKET (INVALID_SOCKET)
+#endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
+#define MHD_SOCKET_DEFINED 1
+#endif /* MHD_SOCKET_DEFINED */
+
+/**
+ * Define MHD_NO_DEPRECATION before including "microhttpd.h" to disable deprecation messages
+ */
+#ifdef MHD_NO_DEPRECATION
+#define _MHD_DEPR_MACRO(msg)
+#define _MHD_NO_DEPR_IN_MACRO 1
+#define _MHD_DEPR_IN_MACRO(msg)
+#define _MHD_NO_DEPR_FUNC 1
+#define _MHD_DEPR_FUNC(msg)
+#endif /* MHD_NO_DEPRECATION */
+
+#ifndef _MHD_DEPR_MACRO
+#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1500
+/* VS 2008 or later */
+/* Stringify macros */
+#define _MHD_INSTRMACRO(a) #a
+#define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a)
+/* deprecation message */
+#define _MHD_DEPR_MACRO(msg) __pragma(message (__FILE__ "(" _MHD_STRMACRO ( \
+ __LINE__) "): warning: " msg))
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
+#elif defined(__clang__) || defined (__GNUC_PATCHLEVEL__)
+/* clang or GCC since 3.0 */
+#define _MHD_GCC_PRAG(x) _Pragma(#x)
+#if (defined(__clang__) && (__clang_major__ + 0 >= 5 || \
+ (! defined(__apple_build_version__) && \
+ (__clang_major__ + 0 > 3 || (__clang_major__ + 0 == 3 && __clang_minor__ >= \
+ 3))))) || \
+ __GNUC__ + 0 > 4 || (__GNUC__ + 0 == 4 && __GNUC_MINOR__ + 0 >= 8)
+/* clang >= 3.3 (or XCode's clang >= 5.0) or
+ GCC >= 4.8 */
+#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (GCC warning msg)
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
+#else /* older clang or GCC */
+/* clang < 3.3, XCode's clang < 5.0, 3.0 <= GCC < 4.8 */
+#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG (message msg)
+#if (defined(__clang__) && (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == \
+ 2 && __clang_minor__ >= \
+ 9))) /* FIXME: clang >= 2.9, earlier versions not tested */
+/* clang handles inline pragmas better than GCC */
+#define _MHD_DEPR_IN_MACRO(msg) _MHD_DEPR_MACRO (msg)
+#endif /* clang >= 2.9 */
+#endif /* older clang or GCC */
+/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
+#endif /* clang || GCC >= 3.0 */
+#endif /* !_MHD_DEPR_MACRO */
+
+#ifndef _MHD_DEPR_MACRO
+#define _MHD_DEPR_MACRO(msg)
+#endif /* !_MHD_DEPR_MACRO */
+
+#ifndef _MHD_DEPR_IN_MACRO
+#define _MHD_NO_DEPR_IN_MACRO 1
+#define _MHD_DEPR_IN_MACRO(msg)
+#endif /* !_MHD_DEPR_IN_MACRO */
+
+#ifndef _MHD_DEPR_FUNC
+#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1400
+/* VS 2005 or later */
+#define _MHD_DEPR_FUNC(msg) __declspec(deprecated (msg))
+#elif defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1310
+/* VS .NET 2003 deprecation do not support custom messages */
+#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)
+#elif (__GNUC__ + 0 >= 5) || (defined (__clang__) && \
+ (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == 2 && __clang_minor__ >= \
+ 9))) /* FIXME: earlier versions not tested */
+/* GCC >= 5.0 or clang >= 2.9 */
+#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated (msg)))
+#elif defined (__clang__) || __GNUC__ + 0 > 3 || (__GNUC__ + 0 == 3 && \
+ __GNUC_MINOR__ + 0 >= 1)
+/* 3.1 <= GCC < 5.0 or clang < 2.9 */
+/* old GCC-style deprecation do not support custom messages */
+#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__))
+/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
+#endif /* clang < 2.9 || GCC >= 3.1 */
+#endif /* !_MHD_DEPR_FUNC */
+
+#ifndef _MHD_DEPR_FUNC
+#define _MHD_NO_DEPR_FUNC 1
+#define _MHD_DEPR_FUNC(msg)
+#endif /* !_MHD_DEPR_FUNC */
+
+
+/* Define MHD_NONNULL attribute */
+
+/**
+ * Macro to indicate that certain parameters must be
+ * non-null. Todo: port to non-gcc platforms.
+ */
+#if defined(__CYGWIN__) || defined(_WIN32) || defined(MHD_W32LIB) || \
+ defined(__clang__) || ! defined(__GNUC__)
+#define MHD_NONNULL(...) /* empty */
+#else
+#define MHD_NONNULL(...) __THROW __nonnull ((__VA_ARGS__))
+#endif
+
+/**
+ * Not all architectures and `printf()`'s support the `long long` type.
+ * This gives the ability to replace `long long` with just a `long`,
+ * standard `int` or a `short`.
+ */
+#ifndef MHD_UNSIGNED_LONG_LONG
+#define MHD_UNSIGNED_LONG_LONG unsigned long long
+#endif
+/**
+ * Format string for printing a variable of type #MHD_LONG_LONG.
+ * You should only redefine this if you also define #MHD_LONG_LONG.
+ */
+#ifndef MHD_UNSIGNED_LONG_LONG_PRINTF
+#define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu"
+#endif
+
+
+/**
+ * @brief Handle for a connection / HTTP request.
+ *
+ * With HTTP/1.1, multiple requests can be run over the same
+ * connection. However, MHD will only show one request per TCP
+ * connection to the client at any given time.
+ *
+ * Replaces `struct MHD_Connection`, renamed to better reflect
+ * what this object truly represents to the application using
+ * MHD.
+ *
+ * @ingroup request
+ */
+struct MHD_Request;
+
+
+/**
+ * A connection corresponds to the network/stream abstraction.
+ * A single network (i.e. TCP) stream may be used for multiple
+ * requests, which in HTTP/1.1 must be processed sequentially.
+ */
+struct MHD_Connection;
+
+
+/**
+ * Return values for reporting errors, also used
+ * for logging.
+ *
+ * A value of 0 indicates success (as a return value).
+ * Values between 0 and 10000 must be handled explicitly by the app.
+ * Values from 10000-19999 are informational.
+ * Values from 20000-29999 indicate successful operations.
+ * Values from 30000-39999 indicate unsuccessful (normal) operations.
+ * Values from 40000-49999 indicate client errors.
+ * Values from 50000-59999 indicate MHD server errors.
+ * Values from 60000-69999 indicate application errors.
+ */
+enum MHD_StatusCode
+{
+
+ /* 00000-level status codes indicate return values
+ the application must act on. */
+
+ /**
+ * Successful operation (not used for logging).
+ */
+ MHD_SC_OK = 0,
+
+ /**
+ * We were asked to return a timeout, but, there is no timeout.
+ */
+ MHD_SC_NO_TIMEOUT = 1,
+
+
+ /* 10000-level status codes indicate intermediate
+ results of some kind. */
+
+ /**
+ * Informational event, MHD started.
+ */
+ MHD_SC_DAEMON_STARTED = 10000,
+
+ /**
+ * Informational event, we accepted a connection.
+ */
+ MHD_SC_CONNECTION_ACCEPTED = 10001,
+
+ /**
+ * Informational event, thread processing connection termiantes.
+ */
+ MHD_SC_THREAD_TERMINATING = 10002,
+
+ /**
+ * Informational event, state machine status for a connection.
+ */
+ MHD_SC_STATE_MACHINE_STATUS_REPORT = 10003,
+
+ /**
+ * accept() returned transient error.
+ */
+ MHD_SC_ACCEPT_FAILED_EAGAIN = 10004,
+
+
+ /* 20000-level status codes indicate success of some kind. */
+
+ /**
+ * MHD is closing a connection after the client closed it
+ * (perfectly normal end).
+ */
+ MHD_SC_CONNECTION_CLOSED = 20000,
+
+ /**
+ * MHD is closing a connection because the application
+ * logic to generate the response data completed.
+ */
+ MHD_SC_APPLICATION_DATA_GENERATION_FINISHED = 20001,
+
+
+ /* 30000-level status codes indicate transient failures
+ that might go away if the client tries again. */
+
+
+ /**
+ * Resource limit in terms of number of parallel connections
+ * hit.
+ */
+ MHD_SC_LIMIT_CONNECTIONS_REACHED = 30000,
+
+ /**
+ * We failed to allocate memory for poll() syscall.
+ * (May be transient.)
+ */
+ MHD_SC_POLL_MALLOC_FAILURE = 30001,
+
+ /**
+ * The operation failed because the respective
+ * daemon is already too deep inside of the shutdown
+ * activity.
+ */
+ MHD_SC_DAEMON_ALREADY_SHUTDOWN = 30002,
+
+ /**
+ * We failed to start a thread.
+ */
+ MHD_SC_THREAD_LAUNCH_FAILURE = 30003,
+
+ /**
+ * The operation failed because we either have no
+ * listen socket or were already quiesced.
+ */
+ MHD_SC_DAEMON_ALREADY_QUIESCED = 30004,
+
+ /**
+ * The operation failed because client disconnected
+ * faster than we could accept().
+ */
+ MHD_SC_ACCEPT_FAST_DISCONNECT = 30005,
+
+ /**
+ * Operating resource limits hit on accept().
+ */
+ MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED = 30006,
+
+ /**
+ * Connection was refused by accept policy callback.
+ */
+ MHD_SC_ACCEPT_POLICY_REJECTED = 30007,
+
+ /**
+ * We failed to allocate memory for the connection.
+ * (May be transient.)
+ */
+ MHD_SC_CONNECTION_MALLOC_FAILURE = 30008,
+
+ /**
+ * We failed to allocate memory for the connection's memory pool.
+ * (May be transient.)
+ */
+ MHD_SC_POOL_MALLOC_FAILURE = 30009,
+
+ /**
+ * We failed to forward data from a Web socket to the
+ * application to the remote side due to the socket
+ * being closed prematurely. (May be transient.)
+ */
+ MHD_SC_UPGRADE_FORWARD_INCOMPLETE = 30010,
+
+ /**
+ * We failed to allocate memory for generating the response from our
+ * memory pool. Likely the request header was too large to leave
+ * enough room.
+ */
+ MHD_SC_CONNECTION_POOL_MALLOC_FAILURE = 30011,
+
+
+ /* 40000-level errors are caused by the HTTP client
+ (or the network) */
+
+ /**
+ * MHD is closing a connection because parsing the
+ * request failed.
+ */
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED = 40000,
+
+ /**
+ * MHD is closing a connection because it was reset.
+ */
+ MHD_SC_CONNECTION_RESET_CLOSED = 40001,
+
+ /**
+ * MHD is closing a connection because reading the
+ * request failed.
+ */
+ MHD_SC_CONNECTION_READ_FAIL_CLOSED = 40002,
+
+ /**
+ * MHD is closing a connection because writing the response failed.
+ */
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED = 40003,
+
+ /**
+ * MHD is returning an error because the header provided
+ * by the client is too big.
+ */
+ MHD_SC_CLIENT_HEADER_TOO_BIG = 40004,
+
+ /**
+ * An HTTP/1.1 request was sent without the "Host:" header.
+ */
+ MHD_SC_HOST_HEADER_MISSING = 40005,
+
+ /**
+ * The given content length was not a number.
+ */
+ MHD_SC_CONTENT_LENGTH_MALFORMED = 40006,
+
+ /**
+ * The given uploaded, chunked-encoded body was malformed.
+ */
+ MHD_SC_CHUNKED_ENCODING_MALFORMED = 40007,
+
+
+ /* 50000-level errors are because of an error internal
+ to the MHD logic, possibly including our interaction
+ with the operating system (but not the application) */
+
+ /**
+ * This build of MHD does not support TLS, but the application
+ * requested TLS.
+ */
+ MHD_SC_TLS_DISABLED = 50000,
+
+ /**
+ * The application attempted to setup TLS parameters before
+ * enabling TLS.
+ */
+ MHD_SC_TLS_BACKEND_UNINITIALIZED = 50003,
+
+ /**
+ * The selected TLS backend does not yet support this operation.
+ */
+ MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED = 50004,
+
+ /**
+ * Failed to setup ITC channel.
+ */
+ MHD_SC_ITC_INITIALIZATION_FAILED = 50005,
+
+ /**
+ * File descriptor for ITC channel too large.
+ */
+ MHD_SC_ITC_DESCRIPTOR_TOO_LARGE = 50006,
+
+ /**
+ * The specified value for the NC length is way too large
+ * for this platform (integer overflow on `size_t`).
+ */
+ MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG = 50007,
+
+ /**
+ * We failed to allocate memory for the specified nonce
+ * counter array. The option was not set.
+ */
+ MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE = 50008,
+
+ /**
+ * This build of the library does not support
+ * digest authentication.
+ */
+ MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD = 50009,
+
+ /**
+ * IPv6 requested but not supported by this build.
+ */
+ MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD = 50010,
+
+ /**
+ * We failed to open the listen socket. Maybe the build
+ * supports IPv6, but your kernel does not?
+ */
+ MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET = 50011,
+
+ /**
+ * Specified address family is not supported by this build.
+ */
+ MHD_SC_AF_NOT_SUPPORTED_BY_BUILD = 50012,
+
+ /**
+ * Failed to enable listen address reuse.
+ */
+ MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED = 50013,
+
+ /**
+ * Enabling listen address reuse is not supported by this platform.
+ */
+ MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED = 50014,
+
+ /**
+ * Failed to disable listen address reuse.
+ */
+ MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED = 50015,
+
+ /**
+ * Disabling listen address reuse is not supported by this platform.
+ */
+ MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED = 50016,
+
+ /**
+ * We failed to explicitly enable or disable dual stack for
+ * the IPv6 listen socket. The socket will be used in whatever
+ * the default is the OS gives us.
+ */
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED = 50017,
+
+ /**
+ * On this platform, MHD does not support explicitly configuring
+ * dual stack behavior.
+ */
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED = 50018,
+
+ /**
+ * Failed to enable TCP FAST OPEN option.
+ */
+ MHD_SC_FAST_OPEN_FAILURE = 50020,
+
+ /**
+ * Failed to start listening on listen socket.
+ */
+ MHD_SC_LISTEN_FAILURE = 50021,
+
+ /**
+ * Failed to obtain our listen port via introspection.
+ */
+ MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE = 50022,
+
+ /**
+ * Failed to obtain our listen port via introspection
+ * due to unsupported address family being used.
+ */
+ MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF = 50023,
+
+ /**
+ * We failed to set the listen socket to non-blocking.
+ */
+ MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE = 50024,
+
+ /**
+ * Listen socket value is too large (for use with select()).
+ */
+ MHD_SC_LISTEN_SOCKET_TOO_LARGE = 50025,
+
+ /**
+ * We failed to allocate memory for the thread pool.
+ */
+ MHD_SC_THREAD_POOL_MALLOC_FAILURE = 50026,
+
+ /**
+ * We failed to allocate mutex for thread pool worker.
+ */
+ MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE = 50027,
+
+ /**
+ * There was an attempt to upgrade a connection on
+ * a daemon where upgrades are disallowed.
+ */
+ MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED = 50028,
+
+ /**
+ * Failed to signal via ITC channel.
+ */
+ MHD_SC_ITC_USE_FAILED = 50029,
+
+ /**
+ * We failed to initialize the main thread for listening.
+ */
+ MHD_SC_THREAD_MAIN_LAUNCH_FAILURE = 50030,
+
+ /**
+ * We failed to initialize the threads for the worker pool.
+ */
+ MHD_SC_THREAD_POOL_LAUNCH_FAILURE = 50031,
+
+ /**
+ * We failed to add a socket to the epoll() set.
+ */
+ MHD_SC_EPOLL_CTL_ADD_FAILED = 50032,
+
+ /**
+ * We failed to create control socket for the epoll().
+ */
+ MHD_SC_EPOLL_CTL_CREATE_FAILED = 50034,
+
+ /**
+ * We failed to configure control socket for the epoll()
+ * to be non-inheritable.
+ */
+ MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50035,
+
+ /**
+ * We failed to build the FD set because a socket was
+ * outside of the permitted range.
+ */
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE = 50036,
+
+ /**
+ * This daemon was not configured with options that
+ * would allow us to build an FD set for select().
+ */
+ MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_FDSET = 50037,
+
+ /**
+ * This daemon was not configured with options that
+ * would allow us to obtain a meaningful timeout.
+ */
+ MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT = 50038,
+
+ /**
+ * This daemon was not configured with options that
+ * would allow us to run with select() data.
+ */
+ MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_SELECT = 50039,
+
+ /**
+ * This daemon was not configured to run with an
+ * external event loop.
+ */
+ MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL = 50040,
+
+ /**
+ * Encountered an unexpected event loop style
+ * (should never happen).
+ */
+ MHD_SC_CONFIGURATION_UNEXPECTED_ELS = 50041,
+
+ /**
+ * Encountered an unexpected error from select()
+ * (should never happen).
+ */
+ MHD_SC_UNEXPECTED_SELECT_ERROR = 50042,
+
+ /**
+ * poll() is not supported.
+ */
+ MHD_SC_POLL_NOT_SUPPORTED = 50043,
+
+ /**
+ * Encountered an unexpected error from poll()
+ * (should never happen).
+ */
+ MHD_SC_UNEXPECTED_POLL_ERROR = 50044,
+
+ /**
+ * We failed to configure accepted socket
+ * to not use a signal pipe.
+ */
+ MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED = 50045,
+
+ /**
+ * Encountered an unexpected error from epoll_wait()
+ * (should never happen).
+ */
+ MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR = 50046,
+
+ /**
+ * epoll file descriptor is invalid (strange)
+ */
+ MHD_SC_EPOLL_FD_INVALID = 50047,
+
+ /**
+ * We failed to configure accepted socket
+ * to be non-inheritable.
+ */
+ MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED = 50048,
+
+ /**
+ * We failed to configure accepted socket
+ * to be non-blocking.
+ */
+ MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED = 50049,
+
+ /**
+ * accept() returned non-transient error.
+ */
+ MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY = 50050,
+
+ /**
+ * Operating resource limits hit on accept() while
+ * zero connections are active. Oopsie.
+ */
+ MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY = 50051,
+
+ /**
+ * Failed to add IP address to per-IP counter for
+ * some reason.
+ */
+ MHD_SC_IP_COUNTER_FAILURE = 50052,
+
+ /**
+ * Application violated our API by calling shutdown
+ * while having an upgrade connection still open.
+ */
+ MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION = 50053,
+
+ /**
+ * Due to an unexpected internal error with the
+ * state machine, we closed the connection.
+ */
+ MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED = 50054,
+
+ /**
+ * Failed to allocate memory in connection's pool
+ * to parse the cookie header.
+ */
+ MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE = 50055,
+
+ /**
+ * MHD failed to build the response header.
+ */
+ MHD_SC_FAILED_RESPONSE_HEADER_GENERATION = 50056,
+
+
+ /* 60000-level errors are because the application
+ logic did something wrong or generated an error. */
+
+ /**
+ * MHD does not support the requested combination of
+ * EPOLL with thread-per-connection mode.
+ */
+ MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID = 60000,
+
+ /**
+ * MHD does not support quiescing if ITC was disabled
+ * and threads are used.
+ */
+ MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60001,
+
+ /**
+ * We failed to bind the listen socket.
+ */
+ MHD_SC_LISTEN_SOCKET_BIND_FAILED = 60002,
+
+ /**
+ * The application requested an unsupported TLS backend to be used.
+ */
+ MHD_SC_TLS_BACKEND_UNSUPPORTED = 60003,
+
+ /**
+ * The application requested a TLS cipher suite which is not
+ * supported by the selected backend.
+ */
+ MHD_SC_TLS_CIPHERS_INVALID = 60004,
+
+ /**
+ * MHD is closing a connection because the application
+ * logic to generate the response data failed.
+ */
+ MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED = 60005,
+
+ /**
+ * MHD is closing a connection because the application
+ * callback told it to do so.
+ */
+ MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED = 60006,
+
+ /**
+ * Application only partially processed upload and did
+ * not suspend connection. This may result in a hung
+ * connection.
+ */
+ MHD_SC_APPLICATION_HUNG_CONNECTION = 60007,
+
+ /**
+ * Application only partially processed upload and did
+ * not suspend connection and the read buffer was maxxed
+ * out, so MHD closed the connection.
+ */
+ MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED = 60008,
+
+
+};
+
+
+/**
+ * Actions are returned by the application to drive the request
+ * handling of MHD.
+ */
+struct MHD_Action;
+
+
+/**
+ * HTTP methods explicitly supported by MHD. Note that for
+ * non-canonical methods, MHD will return #MHD_METHOD_UNKNOWN
+ * and you can use #MHD_REQUEST_INFORMATION_HTTP_METHOD to get
+ * the original string.
+ *
+ * However, applications must check for "#MHD_METHOD_UNKNOWN" *or* any
+ * enum-value above those in this list, as future versions of MHD may
+ * add additional methods (as per IANA registry), thus even if the API
+ * returns "unknown" today, it may return a method-specific header in
+ * the future!
+ *
+ * @defgroup methods HTTP methods
+ * HTTP methods (as strings).
+ * See: http://www.iana.org/assignments/http-methods/http-methods.xml
+ * Registry Version 2015-05-19
+ * @{
+ */
+enum MHD_Method
+{
+
+ /**
+ * Method did not match any of the methods given below.
+ */
+ MHD_METHOD_UNKNOWN = 0,
+
+ /**
+ * "OPTIONS" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.7.
+ */
+ MHD_METHOD_OPTIONS = 1,
+
+ /**
+ * "GET" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.1.
+ */
+ MHD_METHOD_GET = 2,
+
+ /**
+ * "HEAD" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.2.
+ */
+ MHD_METHOD_HEAD = 3,
+
+ /**
+ * "POST" method.
+ * Not safe. Not idempotent. RFC7231, Section 4.3.3.
+ */
+ MHD_METHOD_POST = 4,
+
+ /**
+ * "PUT" method.
+ * Not safe. Idempotent. RFC7231, Section 4.3.4.
+ */
+ MHD_METHOD_PUT = 5,
+
+ /**
+ * "DELETE" method.
+ * Not safe. Idempotent. RFC7231, Section 4.3.5.
+ */
+ MHD_METHOD_DELETE = 6,
+
+ /**
+ * "TRACE" method.
+ */
+ MHD_METHOD_TRACE = 7,
+
+ /**
+ * "CONNECT" method.
+ */
+ MHD_METHOD_CONNECT = 8,
+
+ /**
+ * "ACL" method.
+ */
+ MHD_METHOD_ACL = 9,
+
+ /**
+ * "BASELINE-CONTROL" method.
+ */
+ MHD_METHOD_BASELINE_CONTROL = 10,
+
+ /**
+ * "BIND" method.
+ */
+ MHD_METHOD_BIND = 11,
+
+ /**
+ * "CHECKIN" method.
+ */
+ MHD_METHOD_CHECKIN = 12,
+
+ /**
+ * "CHECKOUT" method.
+ */
+ MHD_METHOD_CHECKOUT = 13,
+
+ /**
+ * "COPY" method.
+ */
+ MHD_METHOD_COPY = 14,
+
+ /**
+ * "LABEL" method.
+ */
+ MHD_METHOD_LABEL = 15,
+
+ /**
+ * "LINK" method.
+ */
+ MHD_METHOD_LINK = 16,
+
+ /**
+ * "LOCK" method.
+ */
+ MHD_METHOD_LOCK = 17,
+
+ /**
+ * "MERGE" method.
+ */
+ MHD_METHOD_MERGE = 18,
+
+ /**
+ * "MKACTIVITY" method.
+ */
+ MHD_METHOD_MKACTIVITY = 19,
+
+ /**
+ * "MKCOL" method.
+ */
+ MHD_METHOD_MKCOL = 20,
+
+ /**
+ * "MKREDIRECTREF" method.
+ */
+ MHD_METHOD_MKREDIRECTREF = 21,
+
+ /**
+ * "MKWORKSPACE" method.
+ */
+ MHD_METHOD_MKWORKSPACE = 22,
+
+ /**
+ * "MOVE" method.
+ */
+ MHD_METHOD_MOVE = 23,
+
+ /**
+ * "ORDERPATCH" method.
+ */
+ MHD_METHOD_ORDERPATCH = 24,
+
+ /**
+ * "PATCH" method.
+ */
+ MHD_METHOD_PATH = 25,
+
+ /**
+ * "PRI" method.
+ */
+ MHD_METHOD_PRI = 26,
+
+ /**
+ * "PROPFIND" method.
+ */
+ MHD_METHOD_PROPFIND = 27,
+
+ /**
+ * "PROPPATCH" method.
+ */
+ MHD_METHOD_PROPPATCH = 28,
+
+ /**
+ * "REBIND" method.
+ */
+ MHD_METHOD_REBIND = 29,
+
+ /**
+ * "REPORT" method.
+ */
+ MHD_METHOD_REPORT = 30,
+
+ /**
+ * "SEARCH" method.
+ */
+ MHD_METHOD_SEARCH = 31,
+
+ /**
+ * "UNBIND" method.
+ */
+ MHD_METHOD_UNBIND = 32,
+
+ /**
+ * "UNCHECKOUT" method.
+ */
+ MHD_METHOD_UNCHECKOUT = 33,
+
+ /**
+ * "UNLINK" method.
+ */
+ MHD_METHOD_UNLINK = 34,
+
+ /**
+ * "UNLOCK" method.
+ */
+ MHD_METHOD_UNLOCK = 35,
+
+ /**
+ * "UPDATE" method.
+ */
+ MHD_METHOD_UPDATE = 36,
+
+ /**
+ * "UPDATEDIRECTREF" method.
+ */
+ MHD_METHOD_UPDATEDIRECTREF = 37,
+
+ /**
+ * "VERSION-CONTROL" method.
+ */
+ MHD_METHOD_VERSION_CONTROL = 38
+
+ /* For more, check:
+ https://www.iana.org/assignments/http-methods/http-methods.xhtml */
+
+};
+
+/** @} */ /* end of group methods */
+
+
+/**
+ * @defgroup postenc HTTP POST encodings
+ * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
+ * @{
+ */
+#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED \
+ "application/x-www-form-urlencoded"
+#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data"
+
+/** @} */ /* end of group postenc */
+
+
+/**
+ * @defgroup headers HTTP headers
+ * These are the standard headers found in HTTP requests and responses.
+ * See: http://www.iana.org/assignments/message-headers/message-headers.xml
+ * Registry Version 2017-01-27
+ * @{
+ */
+
+/* Main HTTP headers. */
+/* Standard. RFC7231, Section 5.3.2 */
+#define MHD_HTTP_HEADER_ACCEPT "Accept"
+/* Standard. RFC7231, Section 5.3.3 */
+#define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
+/* Standard. RFC7231, Section 5.3.4; RFC7694, Section 3 */
+#define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
+/* Standard. RFC7231, Section 5.3.5 */
+#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
+/* Standard. RFC7233, Section 2.3 */
+#define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
+/* Standard. RFC7234, Section 5.1 */
+#define MHD_HTTP_HEADER_AGE "Age"
+/* Standard. RFC7231, Section 7.4.1 */
+#define MHD_HTTP_HEADER_ALLOW "Allow"
+/* Standard. RFC7235, Section 4.2 */
+#define MHD_HTTP_HEADER_AUTHORIZATION "Authorization"
+/* Standard. RFC7234, Section 5.2 */
+#define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control"
+/* Reserved. RFC7230, Section 8.1 */
+#define MHD_HTTP_HEADER_CLOSE "Close"
+/* Standard. RFC7230, Section 6.1 */
+#define MHD_HTTP_HEADER_CONNECTION "Connection"
+/* Standard. RFC7231, Section 3.1.2.2 */
+#define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
+/* Standard. RFC7231, Section 3.1.3.2 */
+#define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
+/* Standard. RFC7230, Section 3.3.2 */
+#define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
+/* Standard. RFC7231, Section 3.1.4.2 */
+#define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location"
+/* Standard. RFC7233, Section 4.2 */
+#define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range"
+/* Standard. RFC7231, Section 3.1.1.5 */
+#define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type"
+/* Standard. RFC7231, Section 7.1.1.2 */
+#define MHD_HTTP_HEADER_DATE "Date"
+/* Standard. RFC7232, Section 2.3 */
+#define MHD_HTTP_HEADER_ETAG "ETag"
+/* Standard. RFC7231, Section 5.1.1 */
+#define MHD_HTTP_HEADER_EXPECT "Expect"
+/* Standard. RFC7234, Section 5.3 */
+#define MHD_HTTP_HEADER_EXPIRES "Expires"
+/* Standard. RFC7231, Section 5.5.1 */
+#define MHD_HTTP_HEADER_FROM "From"
+/* Standard. RFC7230, Section 5.4 */
+#define MHD_HTTP_HEADER_HOST "Host"
+/* Standard. RFC7232, Section 3.1 */
+#define MHD_HTTP_HEADER_IF_MATCH "If-Match"
+/* Standard. RFC7232, Section 3.3 */
+#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
+/* Standard. RFC7232, Section 3.2 */
+#define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
+/* Standard. RFC7233, Section 3.2 */
+#define MHD_HTTP_HEADER_IF_RANGE "If-Range"
+/* Standard. RFC7232, Section 3.4 */
+#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
+/* Standard. RFC7232, Section 2.2 */
+#define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified"
+/* Standard. RFC7231, Section 7.1.2 */
+#define MHD_HTTP_HEADER_LOCATION "Location"
+/* Standard. RFC7231, Section 5.1.2 */
+#define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
+/* Standard. RFC7231, Appendix A.1 */
+#define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version"
+/* Standard. RFC7234, Section 5.4 */
+#define MHD_HTTP_HEADER_PRAGMA "Pragma"
+/* Standard. RFC7235, Section 4.3 */
+#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
+/* Standard. RFC7235, Section 4.4 */
+#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
+/* Standard. RFC7233, Section 3.1 */
+#define MHD_HTTP_HEADER_RANGE "Range"
+/* Standard. RFC7231, Section 5.5.2 */
+#define MHD_HTTP_HEADER_REFERER "Referer"
+/* Standard. RFC7231, Section 7.1.3 */
+#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After"
+/* Standard. RFC7231, Section 7.4.2 */
+#define MHD_HTTP_HEADER_SERVER "Server"
+/* Standard. RFC7230, Section 4.3 */
+#define MHD_HTTP_HEADER_TE "TE"
+/* Standard. RFC7230, Section 4.4 */
+#define MHD_HTTP_HEADER_TRAILER "Trailer"
+/* Standard. RFC7230, Section 3.3.1 */
+#define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
+/* Standard. RFC7230, Section 6.7 */
+#define MHD_HTTP_HEADER_UPGRADE "Upgrade"
+/* Standard. RFC7231, Section 5.5.3 */
+#define MHD_HTTP_HEADER_USER_AGENT "User-Agent"
+/* Standard. RFC7231, Section 7.1.4 */
+#define MHD_HTTP_HEADER_VARY "Vary"
+/* Standard. RFC7230, Section 5.7.1 */
+#define MHD_HTTP_HEADER_VIA "Via"
+/* Standard. RFC7235, Section 4.1 */
+#define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
+/* Standard. RFC7234, Section 5.5 */
+#define MHD_HTTP_HEADER_WARNING "Warning"
+
+/* Additional HTTP headers. */
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_A_IM "A-IM"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
+/* Informational. RFC7089 */
+#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
+/* No category. RFC5789 */
+#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
+/* Standard. RFC7639, Section 2 */
+#define MHD_HTTP_HEADER_ALPN "ALPN"
+/* Standard. RFC7838 */
+#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc"
+/* Standard. RFC7838 */
+#define MHD_HTTP_HEADER_ALT_USED "Alt-Used"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ALTERNATES "Alternates"
+/* No category. RFC4437 */
+#define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref"
+/* Experimental. RFC8053, Section 4 */
+#define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control"
+/* Standard. RFC7615, Section 3 */
+#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_EXT "C-Ext"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_MAN "C-Man"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_OPT "C-Opt"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_PEP "C-PEP"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info"
+/* Standard. RFC7809, Section 7.1 */
+#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
+/* Obsoleted. RFC2068; RFC2616 */
+#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
+/* Standard. RFC6266 */
+#define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version"
+/* Standard. RFC6265 */
+#define MHD_HTTP_HEADER_COOKIE "Cookie"
+/* Obsoleted. RFC2965; RFC6265 */
+#define MHD_HTTP_HEADER_COOKIE2 "Cookie2"
+/* Standard. RFC5323 */
+#define MHD_HTTP_HEADER_DASL "DASL"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DAV "DAV"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DEPTH "Depth"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DESTINATION "Destination"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DIGEST "Digest"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_EXT "Ext"
+/* Standard. RFC7239 */
+#define MHD_HTTP_HEADER_FORWARDED "Forwarded"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_GETPROFILE "GetProfile"
+/* Experimental. RFC7486, Section 6.1.1 */
+#define MHD_HTTP_HEADER_HOBAREG "Hobareg"
+/* Standard. RFC7540, Section 3.2.1 */
+#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_IM "IM"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_IF "If"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_LABEL "Label"
+/* No category. RFC5988 */
+#define MHD_HTTP_HEADER_LINK "Link"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_MAN "Man"
+/* Informational. RFC7089 */
+#define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_METER "Meter"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_OPT "Opt"
+/* Experimental. RFC8053, Section 3 */
+#define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate"
+/* Standard. RFC4229 */
+#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
+/* Standard. RFC6454 */
+#define MHD_HTTP_HEADER_ORIGIN "Origin"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_OVERWRITE "Overwrite"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_P3P "P3P"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PEP "PEP"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info"
+/* Standard. RFC4229 */
+#define MHD_HTTP_HEADER_POSITION "Position"
+/* Standard. RFC7240 */
+#define MHD_HTTP_HEADER_PREFER "Prefer"
+/* Standard. RFC7240 */
+#define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL "Protocol"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request"
+/* Standard. RFC7615, Section 4 */
+#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PUBLIC "Public"
+/* Standard. RFC7469 */
+#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
+/* Standard. RFC7469 */
+#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \
+ "Public-Key-Pins-Report-Only"
+/* No category. RFC4437 */
+#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SAFE "Safe"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme"
+/* Standard. RFC6265 */
+#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie"
+/* Obsoleted. RFC2965; RFC6265 */
+#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SETPROFILE "SetProfile"
+/* Standard. RFC5023 */
+#define MHD_HTTP_HEADER_SLUG "SLUG"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SOAPACTION "SoapAction"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_STATUS_URI "Status-URI"
+/* Standard. RFC6797 */
+#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_TCN "TCN"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_TIMEOUT "Timeout"
+/* Standard. RFC8030, Section 5.4 */
+#define MHD_HTTP_HEADER_TOPIC "Topic"
+/* Standard. RFC8030, Section 5.2 */
+#define MHD_HTTP_HEADER_TTL "TTL"
+/* Standard. RFC8030, Section 5.3 */
+#define MHD_HTTP_HEADER_URGENCY "Urgency"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_URI "URI"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest"
+/* Informational. RFC7034 */
+#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
+
+/* Some provisional headers. */
+#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \
+ "Access-Control-Allow-Origin"
+/** @} */ /* end of group headers */
+
+
+/**
+ * A client has requested the given url using the given method
+ * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
+ * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc). The callback
+ * must initialize @a rhp to provide further callbacks which will
+ * process the request further and ultimately to provide the response
+ * to give back to the client, or return #MHD_NO.
+ *
+ * @param cls argument given together with the function
+ * pointer when the handler was registered with MHD
+ * @param url the requested url (without arguments after "?")
+ * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
+ * #MHD_HTTP_METHOD_PUT, etc.)
+ * @return action how to proceed, NULL
+ * if the socket must be closed due to a serious
+ * error while handling the request
+ */
+typedef const struct MHD_Action *
+(*MHD_RequestCallback) (void *cls,
+ struct MHD_Request *request,
+ const char *url,
+ enum MHD_Method method);
+
+
+/**
+ * Create (but do not yet start) an MHD daemon.
+ * Usually, you will want to set various options before
+ * starting the daemon with #MHD_daemon_start().
+ *
+ * @param cb function to be called for incoming requests
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
+ */
+_MHD_EXTERN struct MHD_Daemon *
+MHD_daemon_create (MHD_RequestCallback cb,
+ void *cb_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Start a webserver.
+ *
+ * @param daemon daemon to start; you can no longer set
+ * options on this daemon after this call!
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_start (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Stop accepting connections from the listening socket. Allows
+ * clients to continue processing, but stops accepting new
+ * connections. Note that the caller is responsible for closing the
+ * returned socket; however, if MHD is run using threads (anything but
+ * external select mode), it must not be closed until AFTER
+ * #MHD_stop_daemon has been called (as it is theoretically possible
+ * that an existing thread is still using it).
+ *
+ * Note that some thread modes require the caller to have passed
+ * #MHD_USE_ITC when using this API. If this daemon is
+ * in one of those modes and this option was not given to
+ * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.
+ *
+ * @param daemon daemon to stop accepting new connections for
+ * @return old listen socket on success, #MHD_INVALID_SOCKET if
+ * the daemon was already not listening anymore, or
+ * was never started
+ * @ingroup specialized
+ */
+_MHD_EXTERN MHD_socket
+MHD_daemon_quiesce (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Shutdown and destroy an HTTP daemon.
+ *
+ * @param daemon daemon to stop
+ * @ingroup event
+ */
+_MHD_EXTERN void
+MHD_daemon_destroy (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Add another client connection to the set of connections managed by
+ * MHD. This API is usually not needed (since MHD will accept inbound
+ * connections on the server socket). Use this API in special cases,
+ * for example if your HTTP server is behind NAT and needs to connect
+ * out to the HTTP client, or if you are building a proxy.
+ *
+ * If you use this API in conjunction with a internal select or a
+ * thread pool, you must set the option #MHD_USE_ITC to ensure that
+ * the freshly added connection is immediately processed by MHD.
+ *
+ * The given client socket will be managed (and closed!) by MHD after
+ * this call and must no longer be used directly by the application
+ * afterwards.
+ *
+ * @param daemon daemon that manages the connection
+ * @param client_socket socket to manage (MHD will expect
+ * to receive an HTTP request from this socket next).
+ * @param addr IP address of the client
+ * @param addrlen number of bytes in @a addr
+ * @return #MHD_SC_OK on success
+ * The socket will be closed in any case; `errno` is
+ * set to indicate further details about the error.
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_add_connection (struct MHD_Daemon *daemon,
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+MHD_NONNULL (1);
+
+
+/**
+ * Obtain the `select()` sets for this daemon. Daemon's FDs will be
+ * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO
+ * for each fd_set before calling this function. FD_SETSIZE is assumed
+ * to be platform's default.
+ *
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'. In the latter
+ * case, it will only add the single 'epoll()' file descriptor used by
+ * MHD to the sets. It's necessary to use #MHD_get_timeout() in
+ * combination with this function.
+ *
+ * This function must be called only for daemon started without
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @return #MHD_SC_OK on success, otherwise error code
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd)
+MHD_NONNULL (1,2,3,4);
+
+
+/**
+ * Obtain the `select()` sets for this daemon. Daemon's FDs will be
+ * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO
+ * for each fd_set before calling this function.
+ *
+ * Passing custom FD_SETSIZE as @a fd_setsize allow usage of
+ * larger/smaller than platform's default fd_sets.
+ *
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'. In the latter
+ * case, it will only add the single 'epoll' file descriptor used by
+ * MHD to the sets. It's necessary to use #MHD_get_timeout() in
+ * combination with this function.
+ *
+ * This function must be called only for daemon started
+ * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_SC_OK on success, otherwise error code
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+MHD_NONNULL (1,2,3,4);
+
+
+/**
+ * Obtain the `select()` sets for this daemon. Daemon's FDs will be
+ * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO
+ * for each fd_set before calling this function. Size of fd_set is
+ * determined by current value of FD_SETSIZE. It's necessary to use
+ * #MHD_get_timeout() in combination with this function.
+ *
+ * This function could be called only for daemon started
+ * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or any FD didn't
+ * fit fd_set.
+ * @ingroup event
+ */
+#define MHD_daemon_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set, \
+ max_fd) \
+ MHD_get_fdset2 ((daemon),(read_fd_set),(write_fd_set),(except_fd_set), \
+ (max_fd),FD_SETSIZE)
+
+
+/**
+ * Obtain timeout value for polling function for this daemon.
+ * This function set value to amount of milliseconds for which polling
+ * function (`select()` or `poll()`) should at most block, not the
+ * timeout value set for connections.
+ * It is important to always use this function, even if connection
+ * timeout is not set, as in some cases MHD may already have more
+ * data to process on next turn (data pending in TLS buffers,
+ * connections are already ready with epoll etc.) and returned timeout
+ * will be zero.
+ *
+ * @param daemon daemon to query for timeout
+ * @param timeout set to the timeout (in milliseconds)
+ * @return #MHD_SC_OK on success, #MHD_SC_NO_TIMEOUT if timeouts are
+ * not used (or no connections exist that would
+ * necessitate the use of a timeout right now), otherwise
+ * an error code
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
+ MHD_UNSIGNED_LONG_LONG *timeout)
+MHD_NONNULL (1,2);
+
+
+/**
+ * Run webserver operations (without blocking unless in client
+ * callbacks). This method should be called by clients in combination
+ * with #MHD_get_fdset if the client-controlled select method is used
+ * and #MHD_get_timeout().
+ *
+ * This function is a convenience method, which is useful if the
+ * fd_sets from #MHD_get_fdset were not directly passed to `select()`;
+ * with this function, MHD will internally do the appropriate `select()`
+ * call itself again. While it is always safe to call #MHD_run (if
+ * #MHD_USE_INTERNAL_POLLING_THREAD is not set), you should call
+ * #MHD_run_from_select if performance is important (as it saves an
+ * expensive call to `select()`).
+ *
+ * @param daemon daemon to run
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_run (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Run webserver operations. This method should be called by clients
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
+ *
+ * You can use this function instead of #MHD_run if you called
+ * `select()` on the result from #MHD_get_fdset. File descriptors in
+ * the sets that are not controlled by MHD will be ignored. Calling
+ * this function instead of #MHD_run is more efficient as MHD will not
+ * have to call `select()` again to determine which operations are
+ * ready.
+ *
+ * This function cannot be used with daemon started with
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to run select loop for
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
+ const fd_set *read_fd_set,
+ const fd_set *write_fd_set,
+ const fd_set *except_fd_set)
+MHD_NONNULL (1,2,3,4);
+
+
+/* ********************* daemon options ************** */
+
+
+/**
+ * Type of a callback function used for logging by MHD.
+ *
+ * @param cls closure
+ * @param sc status code of the event
+ * @param fm format string (`printf()`-style)
+ * @param ap arguments to @a fm
+ * @ingroup logging
+ */
+typedef void
+(*MHD_LoggingCallback)(void *cls,
+ enum MHD_StatusCode sc,
+ const char *fm,
+ va_list ap);
+
+
+/**
+ * Set logging method. Specify NULL to disable logging entirely. By
+ * default (if this option is not given), we log error messages to
+ * stderr.
+ *
+ * @param daemon which instance to setup logging for
+ * @param logger function to invoke
+ * @param logger_cls closure for @a logger
+ */
+_MHD_EXTERN void
+MHD_daemon_set_logger (struct MHD_Daemon *daemon,
+ MHD_LoggingCallback logger,
+ void *logger_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Convenience macro used to disable logging.
+ *
+ * @param daemon which instance to disable logging for
+ */
+#define MHD_daemon_disable_logging(daemon) MHD_daemon_set_logger (daemon, NULL, \
+ NULL)
+
+
+/**
+ * Suppress use of "Date" header as this system has no RTC.
+ *
+ * @param daemon which instance to disable clock for.
+ */
+_MHD_EXTERN void
+MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Disable use of inter-thread communication channel.
+ * #MHD_daemon_disable_itc() can be used with
+ * #MHD_daemon_thread_internal() to perform some additional
+ * optimizations (in particular, not creating a pipe for IPC
+ * signalling). If it is used, certain functions like
+ * #MHD_daemon_quiesce() or #MHD_connection_add() or
+ * #MHD_action_suspend() cannot be used anymore.
+ * #MHD_daemon_disable_itc() is not beneficial on platforms where
+ * select()/poll()/other signal shutdown() of a listen socket.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to disable itc for
+ */
+_MHD_EXTERN void
+MHD_daemon_disable_itc (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Enable `turbo`. Disables certain calls to `shutdown()`,
+ * enables aggressive non-blocking optimistic reads and
+ * other potentially unsafe optimizations.
+ * Most effects only happen with #MHD_ELS_EPOLL.
+ *
+ * @param daemon which instance to enable turbo for
+ */
+_MHD_EXTERN void
+MHD_daemon_enable_turbo (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Disable #MHD_action_suspend() functionality.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to disable suspend for
+ */
+_MHD_EXTERN void
+MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * You need to set this option if you want to disable use of HTTP "Upgrade".
+ * "Upgrade" may require usage of additional internal resources,
+ * which we can avoid providing if they will not be used.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to enable suspend/resume for
+ */
+_MHD_EXTERN void
+MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Possible levels of enforcement for TCP_FASTOPEN.
+ */
+enum MHD_FastOpenMethod
+{
+ /**
+ * Disable use of TCP_FASTOPEN.
+ */
+ MHD_FOM_DISABLE = -1,
+
+ /**
+ * Enable TCP_FASTOPEN where supported (Linux with a kernel >= 3.6).
+ * This is the default.
+ */
+ MHD_FOM_AUTO = 0,
+
+ /**
+ * If TCP_FASTOPEN is not available, return #MHD_NO.
+ * Also causes #MHD_daemon_start() to fail if setting
+ * the option fails later.
+ */
+ MHD_FOM_REQUIRE = 1
+};
+
+
+/**
+ * Configure TCP_FASTOPEN option, including setting a
+ * custom @a queue_length.
+ *
+ * Note that having a larger queue size can cause resource exhaustion
+ * attack as the TCP stack has to now allocate resources for the SYN
+ * packet along with its DATA.
+ *
+ * @param daemon which instance to configure TCP_FASTOPEN for
+ * @param fom under which conditions should we use TCP_FASTOPEN?
+ * @param queue_length queue length to use, default is 50 if this
+ * option is never given.
+ * @return #MHD_YES upon success, #MHD_NO if #MHD_FOM_REQUIRE was
+ * given, but TCP_FASTOPEN is not available on the platform
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
+ enum MHD_FastOpenMethod fom,
+ unsigned int queue_length)
+MHD_NONNULL (1);
+
+
+/**
+ * Address family to be used by MHD.
+ */
+enum MHD_AddressFamily
+{
+ /**
+ * Option not given, do not listen at all
+ * (unless listen socket or address specified by
+ * other means).
+ */
+ MHD_AF_NONE = 0,
+
+ /**
+ * Pick "best" available method automatically.
+ */
+ MHD_AF_AUTO,
+
+ /**
+ * Use IPv4.
+ */
+ MHD_AF_INET4,
+
+ /**
+ * Use IPv6.
+ */
+ MHD_AF_INET6,
+
+ /**
+ * Use dual stack.
+ */
+ MHD_AF_DUAL
+};
+
+
+/**
+ * Bind to the given TCP port and address family.
+ *
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ * Ineffective in conjunction with #MHD_daemon_bind_sa().
+ *
+ * If neither this option nor the other two mentioned above
+ * is specified, MHD will simply not listen on any socket!
+ *
+ * @param daemon which instance to configure the TCP port for
+ * @param af address family to use
+ * @param port port to use, 0 to bind to a random (free) port
+ */
+_MHD_EXTERN void
+MHD_daemon_bind_port (struct MHD_Daemon *daemon,
+ enum MHD_AddressFamily af,
+ uint16_t port)
+MHD_NONNULL (1);
+
+
+/**
+ * Bind to the given socket address.
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon which instance to configure the binding address for
+ * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
+ * or even a UNIX domain socket (AF_UNIX)
+ * @param sa_len number of bytes in @a sa
+ */
+_MHD_EXTERN void
+MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
+ const struct sockaddr *sa,
+ size_t sa_len)
+MHD_NONNULL (1);
+
+
+/**
+ * Use the given backlog for the listen() call.
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon which instance to configure the backlog for
+ * @param listen_backlog backlog to use
+ */
+_MHD_EXTERN void
+MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
+ int listen_backlog)
+MHD_NONNULL (1);
+
+
+/**
+ * If present true, allow reusing address:port socket (by using
+ * SO_REUSEPORT on most platform, or platform-specific ways). If
+ * present and set to false, disallow reusing address:port socket
+ * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on
+ * Windows).
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon daemon to configure address reuse for
+ */
+_MHD_EXTERN void
+MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Accept connections from the given socket. Socket
+ * must be a TCP or UNIX domain (stream) socket.
+ *
+ * Unless -1 is given, this disables other listen options, including
+ * #MHD_daemon_bind_sa(), #MHD_daemon_bind_port(),
+ * #MHD_daemon_listen_queue() and
+ * #MHD_daemon_listen_allow_address_reuse().
+ *
+ * @param daemon daemon to set listen socket for
+ * @param listen_socket listen socket to use,
+ * MHD_INVALID_SOCKET value will cause this call to be
+ * ignored (other binding options may still be effective)
+ */
+_MHD_EXTERN void
+MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
+ MHD_socket listen_socket)
+MHD_NONNULL (1);
+
+
+/**
+ * Event loop syscalls supported by MHD.
+ */
+enum MHD_EventLoopSyscall
+{
+ /**
+ * Automatic selection of best-available method. This is also the
+ * default.
+ */
+ MHD_ELS_AUTO = 0,
+
+ /**
+ * Use select().
+ */
+ MHD_ELS_SELECT = 1,
+
+ /**
+ * Use poll().
+ */
+ MHD_ELS_POLL = 2,
+
+ /**
+ * Use epoll().
+ */
+ MHD_ELS_EPOLL = 3
+};
+
+
+/**
+ * Force use of a particular event loop system call.
+ *
+ * @param daemon daemon to set event loop style for
+ * @param els event loop syscall to use
+ * @return #MHD_NO on failure, #MHD_YES on success
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_daemon_event_loop (struct MHD_Daemon *daemon,
+ enum MHD_EventLoopSyscall els)
+MHD_NONNULL (1);
+
+
+/**
+ * Protocol strictness enforced by MHD on clients.
+ */
+enum MHD_ProtocolStrictLevel
+{
+ /**
+ * Be particularly permissive about the protocol, allowing slight
+ * deviations that are technically not allowed by the
+ * RFC. Specifically, at the moment, this flag causes MHD to allow
+ * spaces in header field names. This is disallowed by the standard.
+ * It is not recommended to set this value on publicly available
+ * servers as it may potentially lower level of protection.
+ */
+ MHD_PSL_PERMISSIVE = -1,
+
+ /**
+ * Sane level of protocol enforcement for production use.
+ */
+ MHD_PSL_DEFAULT = 0,
+
+ /**
+ * Be strict about the protocol (as opposed to as tolerant as
+ * possible). Specifically, at the moment, this flag causes MHD to
+ * reject HTTP 1.1 connections without a "Host" header. This is
+ * required by the standard, but of course in violation of the "be
+ * as liberal as possible in what you accept" norm. It is
+ * recommended to set this if you are testing clients against
+ * MHD, and to use default in production.
+ */
+ MHD_PSL_STRICT = 1
+};
+
+
+/**
+ * Set how strictly MHD will enforce the HTTP protocol.
+ *
+ * @param daemon daemon to configure strictness for
+ * @param sl how strict should we be
+ */
+_MHD_EXTERN void
+MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
+ enum MHD_ProtocolStrictLevel sl)
+MHD_NONNULL (1);
+
+
+/**
+ * Use SHOUTcast. This will cause the response to begin
+ * with the SHOUTcast "ICY" line instead of "HTTP".
+ *
+ * @param daemon daemon to set SHOUTcast option for
+ */
+_MHD_EXTERN void
+MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+
+/**
+ * Enable and configure TLS.
+ *
+ * @param daemon which instance should be configured
+ * @param tls_backend which TLS backend should be used,
+ * currently only "gnutls" is supported. You can
+ * also specify NULL for best-available (which is the default).
+ * @param ciphers which ciphers should be used by TLS, default is
+ * "NORMAL"
+ * @return status code, #MHD_SC_OK upon success
+ * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown
+ * #MHD_TLS_DISABLED if this build of MHD does not support TLS
+ * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported
+ * by this backend
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
+ const char *tls_backend,
+ const char *ciphers)
+MHD_NONNULL (1);
+
+
+/**
+ * Provide TLS key and certificate data in-memory.
+ *
+ * @param daemon which instance should be configured
+ * @param mem_key private key (key.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param mem_cert certificate (cert.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param pass passphrase phrase to decrypt 'key.pem', NULL
+ * if @param mem_key is in cleartext already
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
+ const char *mem_key,
+ const char *mem_cert,
+ const char *pass)
+MHD_NONNULL (1,2,3);
+
+
+/**
+ * Configure DH parameters (dh.pem) to use for the TLS key
+ * exchange.
+ *
+ * @param daemon daemon to configure tls for
+ * @param dh parameters to use
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
+ const char *dh)
+MHD_NONNULL (1);
+
+
+/**
+ * Function called to lookup the pre shared key (@a psk) for a given
+ * HTTP connection based on the @a username.
+ *
+ * @param cls closure
+ * @param connection the HTTPS connection
+ * @param username the user name claimed by the other side
+ * @param[out] psk to be set to the pre-shared-key; should be allocated with malloc(),
+ * will be freed by MHD
+ * @param[out] psk_size to be set to the number of bytes in @a psk
+ * @return 0 on success, -1 on errors
+ */
+typedef int
+(*MHD_PskServerCredentialsCallback)(void *cls,
+ const struct MHD_Connection *connection,
+ const char *username,
+ void **psk,
+ size_t *psk_size);
+
+
+/**
+ * Configure PSK to use for the TLS key exchange.
+ *
+ * @param daemon daemon to configure tls for
+ * @param psk_cb function to call to obtain pre-shared key
+ * @param psk_cb_cls closure for @a psk_cb
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_set_tls_psk_callback (struct MHD_Daemon *daemon,
+ MHD_PskServerCredentialsCallback psk_cb,
+ void *psk_cb_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Memory pointer for the certificate (ca.pem) to be used by the
+ * HTTPS daemon for client authentication.
+ *
+ * @param daemon daemon to configure tls for
+ * @param mem_trust memory pointer to the certificate
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
+ const char *mem_trust)
+MHD_NONNULL (1);
+
+
+/**
+ * Configure daemon credentials type for GnuTLS.
+ *
+ * @param gnutls_credentials must be a value of
+ * type `gnutls_credentials_type_t`
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
+ int gnutls_credentials)
+MHD_NONNULL (1);
+
+
+/**
+ * Provide TLS key and certificate data via callback.
+ *
+ * Use a callback to determine which X.509 certificate should be used
+ * for a given HTTPS connection. This option provides an alternative
+ * to #MHD_daemon_tls_key_and_cert_from_memory(). You must use this
+ * version if multiple domains are to be hosted at the same IP address
+ * using TLS's Server Name Indication (SNI) extension. In this case,
+ * the callback is expected to select the correct certificate based on
+ * the SNI information provided. The callback is expected to access
+ * the SNI data using `gnutls_server_name_get()`. Using this option
+ * requires GnuTLS 3.0 or higher.
+ *
+ * @param daemon daemon to configure callback for
+ * @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
+ * @return #MHD_SC_OK on success
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
+ void *cb)
+MHD_NONNULL (1);
+
+
+/**
+ * Which threading mode should be used by MHD?
+ */
+enum MHD_ThreadingMode
+{
+
+ /**
+ * MHD should create its own thread for listening and furthermore
+ * create another thread per connection to handle requests. Use
+ * this if handling requests is CPU-intensive or blocking, your
+ * application is thread-safe and you have plenty of memory (per
+ * request).
+ */
+ MHD_TM_THREAD_PER_CONNECTION = -1,
+
+ /**
+ * Use an external event loop. This is the default.
+ */
+ MHD_TM_EXTERNAL_EVENT_LOOP = 0,
+
+ /**
+ * Run with one or more worker threads. Any positive value
+ * means that MHD should start that number of worker threads
+ * (so > 1 is a thread pool) and distributed processing of
+ * requests among the workers.
+ *
+ * A good way to express the use of a thread pool
+ * in your code would be to write "MHD_TM_THREAD_POOL(4)"
+ * to indicate four threads.
+ *
+ * If a positive value is set, * #MHD_daemon_run() and
+ * #MHD_daemon_run_from_select() cannot be used.
+ */
+ MHD_TM_WORKER_THREADS = 1
+
+};
+
+
+/**
+ * Use a thread pool of size @a n.
+ *
+ * @return an `enum MHD_ThreadingMode` for a thread pool of size @a n
+ */
+#define MHD_TM_THREAD_POOL(n) ((enum MHD_ThreadingMode) (n))
+
+
+/**
+ * Specify threading mode to use.
+ *
+ * @param daemon daemon to configure
+ * @param tm mode to use (positive values indicate the
+ * number of worker threads to be used)
+ */
+_MHD_EXTERN void
+MHD_daemon_threading_mode (struct MHD_Daemon *daemon,
+ enum MHD_ThreadingMode tm)
+MHD_NONNULL (1);
+
+
+/**
+ * Allow or deny a client to connect.
+ *
+ * @param cls closure
+ * @param addr address information from the client
+ * @param addrlen length of @a addr
+ * @see #MHD_daemon_accept_policy()
+ * @return #MHD_YES if connection is allowed, #MHD_NO if not
+ */
+typedef enum MHD_Bool
+(*MHD_AcceptPolicyCallback)(void *cls,
+ const struct sockaddr *addr,
+ size_t addrlen);
+
+
+/**
+ * Set a policy callback that accepts/rejects connections
+ * based on the client's IP address. This function will be called
+ * before a connection object is created.
+ *
+ * @param daemon daemon to set policy for
+ * @param apc function to call to check the policy
+ * @param apc_cls closure for @a apc
+ */
+_MHD_EXTERN void
+MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
+ MHD_AcceptPolicyCallback apc,
+ void *apc_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Function called by MHD to allow the application to log
+ * the full @a uri of a @a request.
+ *
+ * @param cls client-defined closure
+ * @param uri the full URI from the HTTP request
+ * @param request the HTTP request handle (headers are
+ * not yet available)
+ * @return value to set for the "request_context" of @a request
+ */
+typedef void *
+(*MHD_EarlyUriLogCallback)(void *cls,
+ const char *uri,
+ struct MHD_Request *request);
+
+
+/**
+ * Register a callback to be called first for every request
+ * (before any parsing of the header). Makes it easy to
+ * log the full URL.
+ *
+ * @param daemon daemon for which to set the logger
+ * @param cb function to call
+ * @param cb_cls closure for @a cb
+ */
+_MHD_EXTERN void
+MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
+ MHD_EarlyUriLogCallback cb,
+ void *cb_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * The `enum MHD_ConnectionNotificationCode` specifies types
+ * of connection notifications.
+ * @ingroup request
+ */
+enum MHD_ConnectionNotificationCode
+{
+
+ /**
+ * A new connection has been started.
+ * @ingroup request
+ */
+ MHD_CONNECTION_NOTIFY_STARTED = 0,
+
+ /**
+ * A connection is closed.
+ * @ingroup request
+ */
+ MHD_CONNECTION_NOTIFY_CLOSED = 1
+
+};
+
+
+/**
+ * Signature of the callback used by MHD to notify the
+ * application about started/stopped connections
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param socket_context socket-specific pointer where the
+ * client can associate some state specific
+ * to the TCP connection; note that this is
+ * different from the "con_cls" which is per
+ * HTTP request. The client can initialize
+ * during #MHD_CONNECTION_NOTIFY_STARTED and
+ * cleanup during #MHD_CONNECTION_NOTIFY_CLOSED
+ * and access in the meantime using
+ * #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+ * @param toe reason for connection notification
+ * @see #MHD_OPTION_NOTIFY_CONNECTION
+ * @ingroup request
+ */
+typedef void
+(*MHD_NotifyConnectionCallback) (void *cls,
+ struct MHD_Connection *connection,
+ enum MHD_ConnectionNotificationCode toe);
+
+
+/**
+ * Register a function that should be called whenever a connection is
+ * started or closed.
+ *
+ * @param daemon daemon to set callback for
+ * @param ncc function to call to check the policy
+ * @param ncc_cls closure for @a apc
+ */
+_MHD_EXTERN void
+MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
+ MHD_NotifyConnectionCallback ncc,
+ void *ncc_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Maximum memory size per connection.
+ * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).
+ * Values above 128k are unlikely to result in much benefit, as half
+ * of the memory will be typically used for IO, and TCP buffers are
+ * unlikely to support window sizes above 64k on most systems.
+ *
+ * @param daemon daemon to configure
+ * @param memory_limit_b connection memory limit to use in bytes
+ * @param memory_increment_b increment to use when growing the read buffer, must be smaller than @a memory_limit_b
+ */
+_MHD_EXTERN void
+MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
+ size_t memory_limit_b,
+ size_t memory_increment_b)
+MHD_NONNULL (1);
+
+
+/**
+ * Desired size of the stack for threads created by MHD. Use 0 for
+ * system default. Only useful if the selected threading mode
+ * is not #MHD_TM_EXTERNAL_EVENT_LOOP.
+ *
+ * @param daemon daemon to configure
+ * @param stack_limit_b stack size to use in bytes
+ */
+_MHD_EXTERN void
+MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
+ size_t stack_limit_b)
+MHD_NONNULL (1);
+
+
+/**
+ * Set maximum number of concurrent connections to accept. If not
+ * given, MHD will not enforce any limits (modulo running into
+ * OS limits). Values of 0 mean no limit.
+ *
+ * @param daemon daemon to configure
+ * @param global_connection_limit maximum number of (concurrent)
+ connections
+ * @param ip_connection_limit limit on the number of (concurrent)
+ * connections made to the server from the same IP address.
+ * Can be used to prevent one IP from taking over all of
+ * the allowed connections. If the same IP tries to
+ * establish more than the specified number of
+ * connections, they will be immediately rejected.
+ */
+_MHD_EXTERN void
+MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
+ unsigned int global_connection_limit,
+ unsigned int ip_connection_limit)
+MHD_NONNULL (1);
+
+
+/**
+ * After how many seconds of inactivity should a
+ * connection automatically be timed out?
+ * Use zero for no timeout, which is also the (unsafe!) default.
+ *
+ * @param daemon daemon to configure
+ * @param timeout_s number of seconds of timeout to use
+ */
+_MHD_EXTERN void
+MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
+ unsigned int timeout_s)
+MHD_NONNULL (1);
+
+
+/**
+ * Signature of functions performing unescaping of strings.
+ * The return value must be "strlen(s)" and @a s should be
+ * updated. Note that the unescape function must not lengthen @a s
+ * (the result must be shorter than the input and still be
+ * 0-terminated).
+ *
+ * @param cls closure
+ * @param req the request for which unescaping is performed
+ * @param[in,out] s string to unescape
+ * @return number of characters in @a s (excluding 0-terminator)
+ */
+typedef size_t
+(*MHD_UnescapeCallback) (void *cls,
+ struct MHD_Request *req,
+ char *s);
+
+
+/**
+ * Specify a function that should be called for unescaping escape
+ * sequences in URIs and URI arguments. Note that this function
+ * will NOT be used by the `struct MHD_PostProcessor`. If this
+ * option is not specified, the default method will be used which
+ * decodes escape sequences of the form "%HH".
+ *
+ * @param daemon daemon to configure
+ * @param unescape_cb function to use, NULL for default
+ * @param unescape_cb_cls closure for @a unescape_cb
+ */
+_MHD_EXTERN void
+MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
+ MHD_UnescapeCallback unescape_cb,
+ void *unescape_cb_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Set random values to be used by the Digest Auth module. Note that
+ * the application must ensure that @a buf remains allocated and
+ * unmodified while the daemon is running.
+ *
+ * @param daemon daemon to configure
+ * @param buf_size number of bytes in @a buf
+ * @param buf entropy buffer
+ */
+_MHD_EXTERN void
+MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
+ size_t buf_size,
+ const void *buf)
+MHD_NONNULL (1,3);
+
+
+/**
+ * Length of the internal array holding the map of the nonce and
+ * the nonce counter.
+ *
+ * @param daemon daemon to configure
+ * @param nc_length desired array length
+ */
+_MHD_EXTERN enum MHD_StatusCode
+MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
+ size_t nc_length)
+MHD_NONNULL (1);
+
+
+/* ********************* connection options ************** */
+
+
+/**
+ * Set custom timeout for the given connection.
+ * Specified as the number of seconds. Use zero for no timeout.
+ * Calling this function will reset timeout timer.
+ *
+ * @param connection connection to configure timeout for
+ * @param timeout_s new timeout in seconds
+ */
+_MHD_EXTERN void
+MHD_connection_set_timeout (struct MHD_Connection *connection,
+ unsigned int timeout_s)
+MHD_NONNULL (1);
+
+
+/* **************** Request handling functions ***************** */
+
+
+/**
+ * The `enum MHD_ValueKind` specifies the source of
+ * the key-value pairs in the HTTP protocol.
+ */
+enum MHD_ValueKind
+{
+
+ /**
+ * HTTP header (request/response).
+ */
+ MHD_HEADER_KIND = 1,
+
+ /**
+ * Cookies. Note that the original HTTP header containing
+ * the cookie(s) will still be available and intact.
+ */
+ MHD_COOKIE_KIND = 2,
+
+ /**
+ * POST data. This is available only if a content encoding
+ * supported by MHD is used (currently only URL encoding),
+ * and only if the posted content fits within the available
+ * memory pool. Note that in that case, the upload data
+ * given to the #MHD_AccessHandlerCallback will be
+ * empty (since it has already been processed).
+ */
+ MHD_POSTDATA_KIND = 4,
+
+ /**
+ * GET (URI) arguments.
+ */
+ MHD_GET_ARGUMENT_KIND = 8,
+
+ /**
+ * HTTP footer (only for HTTP 1.1 chunked encodings).
+ */
+ MHD_FOOTER_KIND = 16
+};
+
+
+/**
+ * Iterator over key-value pairs. This iterator can be used to
+ * iterate over all of the cookies, headers, or POST-data fields of a
+ * request, and also to iterate over the headers that have been added
+ * to a response.
+ *
+ * @param cls closure
+ * @param kind kind of the header we are looking at
+ * @param key key for the value, can be an empty string
+ * @param value corresponding value, can be NULL
+ * @return #MHD_YES to continue iterating,
+ * #MHD_NO to abort the iteration
+ * @ingroup request
+ */
+typedef int
+(*MHD_KeyValueIterator) (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *value);
+
+
+/**
+ * Get all of the headers from the request.
+ *
+ * @param request request to get values from
+ * @param kind types of values to iterate over, can be a bitmask
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup request
+ */
+_MHD_EXTERN unsigned int
+MHD_request_get_values (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ MHD_KeyValueIterator iterator,
+ void *iterator_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * This function can be used to add an entry to the HTTP headers of a
+ * request (so that the #MHD_request_get_values function will
+ * return them -- and the `struct MHD_PostProcessor` will also see
+ * them). This maybe required in certain situations (see Mantis
+ * #1399) where (broken) HTTP implementations fail to supply values
+ * needed by the post processor (or other parts of the application).
+ *
+ * This function MUST only be called from within the
+ * request callbacks (otherwise, access maybe improperly
+ * synchronized). Furthermore, the client must guarantee that the key
+ * and value arguments are 0-terminated strings that are NOT freed
+ * until the connection is closed. (The easiest way to do this is by
+ * passing only arguments to permanently allocated strings.).
+ *
+ * @param request the request for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value
+ * @param value the value itself
+ * @return #MHD_NO if the operation could not be
+ * performed due to insufficient memory;
+ * #MHD_YES on success
+ * @ingroup request
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_request_set_value (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *value)
+MHD_NONNULL (1,3,4);
+
+
+/**
+ * Get a particular header value. If multiple
+ * values match the kind, return any one of them.
+ *
+ * @param request request to get values from
+ * @param kind what kind of value are we looking for
+ * @param key the header to look for, NULL to lookup 'trailing' value without a key
+ * @return NULL if no such item was found
+ * @ingroup request
+ */
+_MHD_EXTERN const char *
+MHD_request_lookup_value (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ const char *key)
+MHD_NONNULL (1);
+
+
+/**
+ * @defgroup httpcode HTTP response codes.
+ * These are the status codes defined for HTTP responses.
+ * @{
+ */
+/* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
+enum MHD_HTTP_StatusCode
+{
+ MHD_HTTP_CONTINUE = 100,
+ MHD_HTTP_SWITCHING_PROTOCOLS = 101,
+ MHD_HTTP_PROCESSING = 102,
+
+ MHD_HTTP_OK = 200,
+ MHD_HTTP_CREATED = 201,
+ MHD_HTTP_ACCEPTED = 202,
+ MHD_HTTP_NON_AUTHORITATIVE_INFORMATION = 203,
+ MHD_HTTP_NO_CONTENT = 204,
+ MHD_HTTP_RESET_CONTENT = 205,
+ MHD_HTTP_PARTIAL_CONTENT = 206,
+ MHD_HTTP_MULTI_STATUS = 207,
+ MHD_HTTP_ALREADY_REPORTED = 208,
+
+ MHD_HTTP_IM_USED = 226,
+
+ MHD_HTTP_MULTIPLE_CHOICES = 300,
+ MHD_HTTP_MOVED_PERMANENTLY = 301,
+ MHD_HTTP_FOUND = 302,
+ MHD_HTTP_SEE_OTHER = 303,
+ MHD_HTTP_NOT_MODIFIED = 304,
+ MHD_HTTP_USE_PROXY = 305,
+ MHD_HTTP_SWITCH_PROXY = 306, /* IANA: unused */
+ MHD_HTTP_TEMPORARY_REDIRECT = 307,
+ MHD_HTTP_PERMANENT_REDIRECT = 308,
+
+ MHD_HTTP_BAD_REQUEST = 400,
+ MHD_HTTP_UNAUTHORIZED = 401,
+ MHD_HTTP_PAYMENT_REQUIRED = 402,
+ MHD_HTTP_FORBIDDEN = 403,
+ MHD_HTTP_NOT_FOUND = 404,
+ MHD_HTTP_METHOD_NOT_ALLOWED = 405,
+ MHD_HTTP_NOT_ACCEPTABLE = 406,
+/** @deprecated */
+#define MHD_HTTP_METHOD_NOT_ACCEPTABLE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE") \
+ MHD_HTTP_NOT_ACCEPTABLE
+ MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED = 407,
+ MHD_HTTP_REQUEST_TIMEOUT = 408,
+ MHD_HTTP_CONFLICT = 409,
+ MHD_HTTP_GONE = 410,
+ MHD_HTTP_LENGTH_REQUIRED = 411,
+ MHD_HTTP_PRECONDITION_FAILED = 412,
+ MHD_HTTP_PAYLOAD_TOO_LARGE = 413,
+/** @deprecated */
+#define MHD_HTTP_REQUEST_ENTITY_TOO_LARGE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUEST_ENTITY_TOO_LARGE is deprecated, use MHD_HTTP_PAYLOAD_TOO_LARGE") \
+ MHD_HTTP_PAYLOAD_TOO_LARGE
+ MHD_HTTP_URI_TOO_LONG = 414,
+/** @deprecated */
+#define MHD_HTTP_REQUEST_URI_TOO_LONG \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUEST_URI_TOO_LONG is deprecated, use MHD_HTTP_URI_TOO_LONG") \
+ MHD_HTTP_URI_TOO_LONG
+ MHD_HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
+ MHD_HTTP_RANGE_NOT_SATISFIABLE = 416,
+/** @deprecated */
+#define MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE \
+ _MHD_DEPR_IN_MACRO ( \
+ "Value MHD_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE is deprecated, use MHD_HTTP_RANGE_NOT_SATISFIABLE") \
+ MHD_HTTP_RANGE_NOT_SATISFIABLE
+ MHD_HTTP_EXPECTATION_FAILED = 417,
+
+ MHD_HTTP_MISDIRECTED_REQUEST = 421,
+ MHD_HTTP_UNPROCESSABLE_ENTITY = 422,
+ MHD_HTTP_LOCKED = 423,
+ MHD_HTTP_FAILED_DEPENDENCY = 424,
+ MHD_HTTP_UNORDERED_COLLECTION = 425, /* IANA: unused */
+ MHD_HTTP_UPGRADE_REQUIRED = 426,
+
+ MHD_HTTP_PRECONDITION_REQUIRED = 428,
+ MHD_HTTP_TOO_MANY_REQUESTS = 429,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
+
+ MHD_HTTP_NO_RESPONSE = 444, /* IANA: unused */
+
+ MHD_HTTP_RETRY_WITH = 449, /* IANA: unused */
+ MHD_HTTP_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450, /* IANA: unused */
+ MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
+
+ MHD_HTTP_INTERNAL_SERVER_ERROR = 500,
+ MHD_HTTP_NOT_IMPLEMENTED = 501,
+ MHD_HTTP_BAD_GATEWAY = 502,
+ MHD_HTTP_SERVICE_UNAVAILABLE = 503,
+ MHD_HTTP_GATEWAY_TIMEOUT = 504,
+ MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED = 505,
+ MHD_HTTP_VARIANT_ALSO_NEGOTIATES = 506,
+ MHD_HTTP_INSUFFICIENT_STORAGE = 507,
+ MHD_HTTP_LOOP_DETECTED = 508,
+ MHD_HTTP_BANDWIDTH_LIMIT_EXCEEDED = 509, /* IANA: unused */
+ MHD_HTTP_NOT_EXTENDED = 510,
+ MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
+
+};
+
+
+/**
+ * Returns the string reason phrase for a response code.
+ *
+ * If we don't have a string for a status code, we give the first
+ * message in that status code class.
+ */
+_MHD_EXTERN const char *
+MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code);
+
+/** @} */ /* end of group httpcode */
+
+
+/**
+ * @defgroup versions HTTP versions
+ * These strings should be used to match against the first line of the
+ * HTTP header.
+ * @{
+ */
+#define MHD_HTTP_VERSION_1_0 "HTTP/1.0"
+#define MHD_HTTP_VERSION_1_1 "HTTP/1.1"
+
+/** @} */ /* end of group versions */
+
+
+/**
+ * Suspend handling of network data for a given request. This can
+ * be used to dequeue a request from MHD's event loop for a while.
+ *
+ * If you use this API in conjunction with a internal select or a
+ * thread pool, you must set the option #MHD_USE_ITC to
+ * ensure that a resumed request is immediately processed by MHD.
+ *
+ * Suspended requests continue to count against the total number of
+ * requests allowed (per daemon, as well as per IP, if such limits
+ * are set). Suspended requests will NOT time out; timeouts will
+ * restart when the request handling is resumed. While a
+ * request is suspended, MHD will not detect disconnects by the
+ * client.
+ *
+ * The only safe time to suspend a request is from either a
+ * #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a
+ * #MHD_RequestfetchResponseCallback. Suspending a request
+ * at any other time will cause an assertion failure.
+ *
+ * Finally, it is an API violation to call #MHD_daemon_stop() while
+ * having suspended requests (this will at least create memory and
+ * socket leaks or lead to undefined behavior). You must explicitly
+ * resume all requests before stopping the daemon.
+ *
+ * @return action to cause a request to be suspended.
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_suspend (void);
+
+
+/**
+ * Resume handling of network data for suspended request. It is
+ * safe to resume a suspended request at any time. Calling this
+ * function on a request that was not previously suspended will
+ * result in undefined behavior.
+ *
+ * If you are using this function in ``external'' select mode, you must
+ * make sure to run #MHD_run() afterwards (before again calling
+ * #MHD_get_fdset(), as otherwise the change may not be reflected in
+ * the set returned by #MHD_get_fdset() and you may end up with a
+ * request that is stuck until the next network activity.
+ *
+ * @param request the request to resume
+ */
+_MHD_EXTERN void
+MHD_request_resume (struct MHD_Request *request)
+MHD_NONNULL (1);
+
+
+/* **************** Response manipulation functions ***************** */
+
+
+/**
+ * Data transmitted in response to an HTTP request.
+ * Usually the final action taken in response to
+ * receiving a request.
+ */
+struct MHD_Response;
+
+
+/**
+ * Converts a @a response to an action. If @a destroy_after_use
+ * is set, the reference to the @a response is consumed
+ * by the conversion. If @a consume is #MHD_NO, then
+ * the @a response can be converted to actions in the future.
+ * However, the @a response is frozen by this step and
+ * must no longer be modified (i.e. by setting headers).
+ *
+ * @param response response to convert, not NULL
+ * @param destroy_after_use should the response object be consumed?
+ * @return corresponding action, never returns NULL
+ *
+ * Implementation note: internally, this is largely just
+ * a cast (and possibly an RC increment operation),
+ * as a response *is* an action. As no memory is
+ * allocated, this operation cannot fail.
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_from_response (struct MHD_Response *response,
+ enum MHD_Bool destroy_after_use)
+MHD_NONNULL (1);
+
+
+/**
+ * Only respond in conservative HTTP 1.0-mode. In
+ * particular, do not (automatically) sent "Connection" headers and
+ * always close the connection after generating the response.
+ *
+ * @param request the request for which we force HTTP 1.0 to be used
+ */
+_MHD_EXTERN void
+MHD_response_option_v10_only (struct MHD_Response *response)
+MHD_NONNULL (1);
+
+
+/**
+ * The `enum MHD_RequestTerminationCode` specifies reasons
+ * why a request has been terminated (or completed).
+ * @ingroup request
+ */
+enum MHD_RequestTerminationCode
+{
+
+ /**
+ * We finished sending the response.
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_COMPLETED_OK = 0,
+
+ /**
+ * Error handling the connection (resources
+ * exhausted, other side closed connection,
+ * application error accepting request, etc.)
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_WITH_ERROR = 1,
+
+ /**
+ * No activity on the connection for the number
+ * of seconds specified using
+ * #MHD_OPTION_CONNECTION_TIMEOUT.
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_TIMEOUT_REACHED = 2,
+
+ /**
+ * We had to close the session since MHD was being
+ * shut down.
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN = 3,
+
+ /**
+ * We tried to read additional data, but the other side closed the
+ * connection. This error is similar to
+ * #MHD_REQUEST_TERMINATED_WITH_ERROR, but specific to the case where
+ * the connection died because the other side did not send expected
+ * data.
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_READ_ERROR = 4,
+
+ /**
+ * The client terminated the connection by closing the socket
+ * for writing (TCP half-closed); MHD aborted sending the
+ * response according to RFC 2616, section 8.1.4.
+ * @ingroup request
+ */
+ MHD_REQUEST_TERMINATED_CLIENT_ABORT = 5
+
+};
+
+
+/**
+ * Signature of the callback used by MHD to notify the application
+ * about completed requests.
+ *
+ * @param cls client-defined closure
+ * @param toe reason for request termination
+ * @param request_context request context value, as originally
+ * returned by the #MHD_EarlyUriLogCallback
+ * @see #MHD_option_request_completion()
+ * @ingroup request
+ */
+typedef void
+(*MHD_RequestTerminationCallback) (void *cls,
+ enum MHD_RequestTerminationCode toe,
+ void *request_context);
+
+
+/**
+ * Set a function to be called once MHD is finished with the
+ * request.
+ *
+ * @param response which response to set the callback for
+ * @param termination_cb function to call
+ * @param termination_cb_cls closure for @e termination_cb
+ */
+_MHD_EXTERN void
+MHD_response_option_termination_callback (struct MHD_Response *response,
+ MHD_RequestTerminationCallback
+ termination_cb,
+ void *termination_cb_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Callback used by libmicrohttpd in order to obtain content. The
+ * callback is to copy at most @a max bytes of content into @a buf. The
+ * total number of bytes that has been placed into @a buf should be
+ * returned.
+ *
+ * Note that returning zero will cause libmicrohttpd to try again.
+ * Thus, returning zero should only be used in conjunction
+ * with MHD_suspend_connection() to avoid busy waiting.
+ *
+ * @param cls extra argument to the callback
+ * @param pos position in the datastream to access;
+ * note that if a `struct MHD_Response` object is re-used,
+ * it is possible for the same content reader to
+ * be queried multiple times for the same data;
+ * however, if a `struct MHD_Response` is not re-used,
+ * libmicrohttpd guarantees that "pos" will be
+ * the sum of all non-negative return values
+ * obtained from the content reader so far.
+ * @param buf where to copy the data
+ * @param max maximum number of bytes to copy to @a buf (size of @a buf)
+ * @return number of bytes written to @a buf;
+ * 0 is legal unless we are running in internal select mode (since
+ * this would cause busy-waiting); 0 in external select mode
+ * will cause this function to be called again once the external
+ * select calls MHD again;
+ * #MHD_CONTENT_READER_END_OF_STREAM (-1) for the regular
+ * end of transmission (with chunked encoding, MHD will then
+ * terminate the chunk and send any HTTP footers that might be
+ * present; without chunked encoding and given an unknown
+ * response size, MHD will simply close the connection; note
+ * that while returning #MHD_CONTENT_READER_END_OF_STREAM is not technically
+ * legal if a response size was specified, MHD accepts this
+ * and treats it just as #MHD_CONTENT_READER_END_WITH_ERROR;
+ * #MHD_CONTENT_READER_END_WITH_ERROR (-2) to indicate a server
+ * error generating the response; this will cause MHD to simply
+ * close the connection immediately. If a response size was
+ * given or if chunked encoding is in use, this will indicate
+ * an error to the client. Note, however, that if the client
+ * does not know a response size and chunked encoding is not in
+ * use, then clients will not be able to tell the difference between
+ * #MHD_CONTENT_READER_END_WITH_ERROR and #MHD_CONTENT_READER_END_OF_STREAM.
+ * This is not a limitation of MHD but rather of the HTTP protocol.
+ */
+typedef ssize_t
+(*MHD_ContentReaderCallback) (void *cls,
+ uint64_t pos,
+ char *buf,
+ size_t max);
+
+
+/**
+ * This method is called by libmicrohttpd if we are done with a
+ * content reader. It should be used to free resources associated
+ * with the content reader.
+ *
+ * @param cls closure
+ * @ingroup response
+ */
+typedef void
+(*MHD_ContentReaderFreeCallback) (void *cls);
+
+
+/**
+ * Create a response action. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to return
+ * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
+ * @param block_size preferred block size for querying crc (advisory only,
+ * MHD may still call @a crc using smaller chunks); this
+ * is essentially the buffer size used for IO, clients
+ * should pick a value that is appropriate for IO and
+ * memory performance requirements
+ * @param crc callback to use to obtain response data
+ * @param crc_cls extra argument to @a crc
+ * @param crfc callback to call to free @a crc_cls resources
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
+ uint64_t size,
+ size_t block_size,
+ MHD_ContentReaderCallback crc,
+ void *crc_cls,
+ MHD_ContentReaderFreeCallback crfc);
+
+
+/**
+ * Specification for how MHD should treat the memory buffer
+ * given for the response.
+ * @ingroup response
+ */
+enum MHD_ResponseMemoryMode
+{
+
+ /**
+ * Buffer is a persistent (static/global) buffer that won't change
+ * for at least the lifetime of the response, MHD should just use
+ * it, not free it, not copy it, just keep an alias to it.
+ * @ingroup response
+ */
+ MHD_RESPMEM_PERSISTENT,
+
+ /**
+ * Buffer is heap-allocated with `malloc()` (or equivalent) and
+ * should be freed by MHD after processing the response has
+ * concluded (response reference counter reaches zero).
+ * @ingroup response
+ */
+ MHD_RESPMEM_MUST_FREE,
+
+ /**
+ * Buffer is in transient memory, but not on the heap (for example,
+ * on the stack or non-`malloc()` allocated) and only valid during the
+ * call to #MHD_create_response_from_buffer. MHD must make its
+ * own private copy of the data for processing.
+ * @ingroup response
+ */
+ MHD_RESPMEM_MUST_COPY
+
+};
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to use for the response;
+ * #MHD_HTTP_NO_CONTENT is only valid if @a size is 0;
+ * @param size size of the data portion of the response
+ * @param buffer size bytes containing the response's data portion
+ * @param mode flags for buffer management
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
+ size_t size,
+ void *buffer,
+ enum MHD_ResponseMemoryMode mode);
+
+
+/**
+ * Create a response object based on an @a fd from which
+ * data is read. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to return
+ * @param fd file descriptor referring to a file on disk with the
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @param offset offset to start reading from in the file;
+ * reading file beyond 2 GiB may be not supported by OS or
+ * MHD build; see ::MHD_FEATURE_LARGE_FILE
+ * @param size size of the data portion of the response;
+ * sizes larger than 2 GiB may be not supported by OS or
+ * MHD build; see ::MHD_FEATURE_LARGE_FILE
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
+ int fd,
+ uint64_t offset,
+ uint64_t size);
+
+
+/**
+ * Enumeration for operations MHD should perform on the underlying socket
+ * of the upgrade. This API is not finalized, and in particular
+ * the final set of actions is yet to be decided. This is just an
+ * idea for what we might want.
+ */
+enum MHD_UpgradeOperation
+{
+
+ /**
+ * Close the socket, the application is done with it.
+ *
+ * Takes no extra arguments.
+ */
+ MHD_UPGRADE_OPERATION_CLOSE = 0
+
+};
+
+
+/**
+ * Handle given to the application to manage special
+ * actions relating to MHD responses that "upgrade"
+ * the HTTP protocol (i.e. to WebSockets).
+ */
+struct MHD_UpgradeResponseHandle;
+
+
+/**
+ * This connection-specific callback is provided by MHD to
+ * applications (unusual) during the #MHD_UpgradeHandler.
+ * It allows applications to perform 'special' actions on
+ * the underlying socket from the upgrade.
+ *
+ * FIXME: this API still uses the untyped, ugly varargs.
+ * Should we not modernize this one as well?
+ *
+ * @param urh the handle identifying the connection to perform
+ * the upgrade @a action on.
+ * @param operation which operation should be performed
+ * @param ... arguments to the action (depends on the action)
+ * @return #MHD_NO on error, #MHD_YES on success
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_upgrade_operation (struct MHD_UpgradeResponseHandle *urh,
+ enum MHD_UpgradeOperation operation,
+ ...)
+MHD_NONNULL (1);
+
+
+/**
+ * Function called after a protocol "upgrade" response was sent
+ * successfully and the socket should now be controlled by some
+ * protocol other than HTTP.
+ *
+ * Any data already received on the socket will be made available in
+ * @e extra_in. This can happen if the application sent extra data
+ * before MHD send the upgrade response. The application should
+ * treat data from @a extra_in as if it had read it from the socket.
+ *
+ * Note that the application must not close() @a sock directly,
+ * but instead use #MHD_upgrade_action() for special operations
+ * on @a sock.
+ *
+ * Data forwarding to "upgraded" @a sock will be started as soon
+ * as this function return.
+ *
+ * Except when in 'thread-per-connection' mode, implementations
+ * of this function should never block (as it will still be called
+ * from within the main event loop).
+ *
+ * @param cls closure, whatever was given to #MHD_response_create_for_upgrade().
+ * @param connection original HTTP connection handle,
+ * giving the function a last chance
+ * to inspect the original HTTP request
+ * @param con_cls last value left in `con_cls` of the `MHD_AccessHandlerCallback`
+ * @param extra_in if we happened to have read bytes after the
+ * HTTP header already (because the client sent
+ * more than the HTTP header of the request before
+ * we sent the upgrade response),
+ * these are the extra bytes already read from @a sock
+ * by MHD. The application should treat these as if
+ * it had read them from @a sock.
+ * @param extra_in_size number of bytes in @a extra_in
+ * @param sock socket to use for bi-directional communication
+ * with the client. For HTTPS, this may not be a socket
+ * that is directly connected to the client and thus certain
+ * operations (TCP-specific setsockopt(), getsockopt(), etc.)
+ * may not work as expected (as the socket could be from a
+ * socketpair() or a TCP-loopback). The application is expected
+ * to perform read()/recv() and write()/send() calls on the socket.
+ * The application may also call shutdown(), but must not call
+ * close() directly.
+ * @param urh argument for #MHD_upgrade_action()s on this @a connection.
+ * Applications must eventually use this callback to (indirectly)
+ * perform the close() action on the @a sock.
+ */
+typedef void
+(*MHD_UpgradeHandler)(void *cls,
+ struct MHD_Connection *connection,
+ void *con_cls,
+ const char *extra_in,
+ size_t extra_in_size,
+ MHD_socket sock,
+ struct MHD_UpgradeResponseHandle *urh);
+
+
+/**
+ * Create a response object that can be used for 101 UPGRADE
+ * responses, for example to implement WebSockets. After sending the
+ * response, control over the data stream is given to the callback (which
+ * can then, for example, start some bi-directional communication).
+ * If the response is queued for multiple connections, the callback
+ * will be called for each connection. The callback
+ * will ONLY be called after the response header was successfully passed
+ * to the OS; if there are communication errors before, the usual MHD
+ * connection error handling code will be performed.
+ *
+ * MHD will automatically set the correct HTTP status
+ * code (#MHD_HTTP_SWITCHING_PROTOCOLS).
+ * Setting correct HTTP headers for the upgrade must be done
+ * manually (this way, it is possible to implement most existing
+ * WebSocket versions using this API; in fact, this API might be useful
+ * for any protocol switch, not just WebSockets). Note that
+ * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
+ * way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
+ * cannot be generated; instead, MHD will always produce "HTTP/1.1 101
+ * Switching Protocols" (if the response code 101 is used).
+ *
+ * As usual, the response object can be extended with header
+ * information and then be used any number of times (as long as the
+ * header information is not connection-specific).
+ *
+ * @param upgrade_handler function to call with the "upgraded" socket
+ * @param upgrade_handler_cls closure for @a upgrade_handler
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
+ void *upgrade_handler_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Explicitly decrease reference counter of a response object. If the
+ * counter hits zero, destroys a response object and associated
+ * resources. Usually, this is implicitly done by converting a
+ * response to an action and returning the action to MHD.
+ *
+ * @param response response to decrement RC of
+ * @ingroup response
+ */
+_MHD_EXTERN void
+MHD_response_queue_for_destroy (struct MHD_Response *response)
+MHD_NONNULL (1);
+
+
+/**
+ * Add a header line to the response.
+ *
+ * @param response response to add a header to
+ * @param header the header to add
+ * @param content value to add
+ * @return #MHD_NO on error (i.e. invalid header or content format),
+ * or out of memory
+ * @ingroup response
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_response_add_header (struct MHD_Response *response,
+ const char *header,
+ const char *content)
+MHD_NONNULL (1,2,3);
+
+
+/**
+ * Add a tailer line to the response.
+ *
+ * @param response response to add a footer to
+ * @param footer the footer to add
+ * @param content value to add
+ * @return #MHD_NO on error (i.e. invalid footer or content format),
+ * or out of memory
+ * @ingroup response
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_response_add_trailer (struct MHD_Response *response,
+ const char *footer,
+ const char *content)
+MHD_NONNULL (1,2,3);
+
+
+/**
+ * Delete a header (or footer) line from the response.
+ *
+ * @param response response to remove a header from
+ * @param header the header to delete
+ * @param content value to delete
+ * @return #MHD_NO on error (no such header known)
+ * @ingroup response
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_response_del_header (struct MHD_Response *response,
+ const char *header,
+ const char *content)
+MHD_NONNULL (1,2,3);
+
+
+/**
+ * Get all of the headers (and footers) added to a response.
+ *
+ * @param response response to query
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup response
+ */
+_MHD_EXTERN unsigned int
+MHD_response_get_headers (struct MHD_Response *response,
+ MHD_KeyValueIterator iterator,
+ void *iterator_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Get a particular header (or footer) from the response.
+ *
+ * @param response response to query
+ * @param key which header to get
+ * @return NULL if header does not exist
+ * @ingroup response
+ */
+_MHD_EXTERN const char *
+MHD_response_get_header (struct MHD_Response *response,
+ const char *key)
+MHD_NONNULL (1,2);
+
+
+/* ************Upload and PostProcessor functions ********************** */
+
+
+/**
+ * Action telling MHD to continue processing the upload.
+ *
+ * @return action operation, never NULL
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_continue (void);
+
+
+/**
+ * Function to process data uploaded by a client.
+ *
+ * @param cls argument given together with the function
+ * pointer when the handler was registered with MHD
+ * @param upload_data the data being uploaded (excluding headers)
+ * POST data will typically be made available incrementally via
+ * multiple callbacks
+ * @param[in,out] upload_data_size set initially to the size of the
+ * @a upload_data provided; the method must update this
+ * value to the number of bytes NOT processed;
+ * @return action specifying how to proceed, often
+ * #MHD_action_continue() if all is well,
+ * #MHD_action_suspend() to stop reading the upload until
+ * the request is resumed,
+ * NULL to close the socket, or a response
+ * to discard the rest of the upload and return the data given
+ */
+typedef const struct MHD_Action *
+(*MHD_UploadCallback) (void *cls,
+ const char *upload_data,
+ size_t *upload_data_size);
+
+
+/**
+ * Create an action that handles an upload.
+ *
+ * @param uc function to call with uploaded data
+ * @param uc_cls closure for @a uc
+ * @return NULL on error (out of memory)
+ * @ingroup action
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_process_upload (MHD_UploadCallback uc,
+ void *uc_cls)
+MHD_NONNULL (1);
+
+
+/**
+ * Iterator over key-value pairs where the value maybe made available
+ * in increments and/or may not be zero-terminated. Used for
+ * MHD parsing POST data. To access "raw" data from POST or PUT
+ * requests, use #MHD_action_process_upload() instead.
+ *
+ * @param cls user-specified closure
+ * @param kind type of the value, always #MHD_POSTDATA_KIND when called from MHD
+ * @param key 0-terminated key for the value
+ * @param filename name of the uploaded file, NULL if not known
+ * @param content_type mime-type of the data, NULL if not known
+ * @param transfer_encoding encoding of the data, NULL if not known
+ * @param data pointer to @a size bytes of data at the
+ * specified offset
+ * @param off offset of data in the overall value
+ * @param size number of bytes in @a data available
+ * @return action specifying how to proceed, often
+ * #MHD_action_continue() if all is well,
+ * #MHD_action_suspend() to stop reading the upload until
+ * the request is resumed,
+ * NULL to close the socket, or a response
+ * to discard the rest of the upload and return the data given
+ */
+typedef const struct MHD_Action *
+(*MHD_PostDataIterator) (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size);
+
+
+/**
+ * Create an action that parses a POST request.
+ *
+ * This action can be used to (incrementally) parse the data portion
+ * of a POST request. Note that some buggy browsers fail to set the
+ * encoding type. If you want to support those, you may have to call
+ * #MHD_set_connection_value with the proper encoding type before
+ * returning this action (if no supported encoding type is detected,
+ * returning this action will cause a bad request to be returned to
+ * the client).
+ *
+ * @param buffer_size maximum number of bytes to use for
+ * internal buffering (used only for the parsing,
+ * specifically the parsing of the keys). A
+ * tiny value (256-1024) should be sufficient.
+ * Do NOT use a value smaller than 256. For good
+ * performance, use 32 or 64k (i.e. 65536).
+ * @param iter iterator to be called with the parsed data,
+ * Must NOT be NULL.
+ * @param iter_cls first argument to @a iter
+ * @return NULL on error (out of memory, unsupported encoding),
+ * otherwise a PP handle
+ * @ingroup request
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_parse_post (size_t buffer_size,
+ MHD_PostDataIterator iter,
+ void *iter_cls)
+MHD_NONNULL (2);
+
+
+/* ********************** generic query functions ********************** */
+
+
+/**
+ * Select which member of the `struct ConnectionInformation`
+ * union is desired to be returned by #MHD_connection_get_info().
+ */
+enum MHD_ConnectionInformationType
+{
+ /**
+ * What cipher algorithm is being used.
+ * Takes no extra arguments.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CIPHER_ALGO,
+
+ /**
+ *
+ * Takes no extra arguments.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_PROTOCOL,
+
+ /**
+ * Obtain IP address of the client. Takes no extra arguments.
+ * Returns essentially a `struct sockaddr **` (since the API returns
+ * a `union MHD_ConnectionInfo *` and that union contains a `struct
+ * sockaddr *`).
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CLIENT_ADDRESS,
+
+ /**
+ * Get the gnuTLS session handle.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_GNUTLS_SESSION,
+
+ /**
+ * Get the gnuTLS client certificate handle. Dysfunctional (never
+ * implemented, deprecated). Use #MHD_CONNECTION_INFORMATION_GNUTLS_SESSION
+ * to get the `gnutls_session_t` and then call
+ * gnutls_certificate_get_peers().
+ */
+ MHD_CONNECTION_INFORMATION_GNUTLS_CLIENT_CERT,
+
+ /**
+ * Get the `struct MHD_Daemon *` responsible for managing this connection.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_DAEMON,
+
+ /**
+ * Request the file descriptor for the connection socket.
+ * No extra arguments should be passed.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CONNECTION_FD,
+
+ /**
+ * Returns the client-specific pointer to a `void *` that was (possibly)
+ * set during a #MHD_NotifyConnectionCallback when the socket was
+ * first accepted. Note that this is NOT the same as the "con_cls"
+ * argument of the #MHD_AccessHandlerCallback. The "con_cls" is
+ * fresh for each HTTP request, while the "socket_context" is fresh
+ * for each socket.
+ */
+ MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT,
+
+ /**
+ * Get connection timeout
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT,
+
+ /**
+ * Check whether the connection is suspended.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED
+
+
+};
+
+
+/**
+ * Information about a connection.
+ */
+union MHD_ConnectionInformation
+{
+
+ /**
+ * Cipher algorithm used, of type "enum gnutls_cipher_algorithm".
+ */
+ int /* enum gnutls_cipher_algorithm */ cipher_algorithm;
+
+ /**
+ * Protocol used, of type "enum gnutls_protocol".
+ */
+ int /* enum gnutls_protocol */ protocol;
+
+ /**
+ * Amount of second that connection could spend in idle state
+ * before automatically disconnected.
+ * Zero for no timeout (unlimited idle time).
+ */
+ unsigned int connection_timeout;
+
+ /**
+ * Connect socket
+ */
+ MHD_socket connect_fd;
+
+ /**
+ * GNUtls session handle, of type "gnutls_session_t".
+ */
+ void * /* gnutls_session_t */ tls_session;
+
+ /**
+ * GNUtls client certificate handle, of type "gnutls_x509_crt_t".
+ */
+ void * /* gnutls_x509_crt_t */ client_cert;
+
+ /**
+ * Address information for the client.
+ */
+ const struct sockaddr *client_addr;
+
+ /**
+ * Which daemon manages this connection (useful in case there are many
+ * daemons running).
+ */
+ struct MHD_Daemon *daemon;
+
+ /**
+ * Pointer to connection-specific client context. Points to the
+ * same address as the "socket_context" of the
+ * #MHD_NotifyConnectionCallback.
+ */
+ void **socket_context;
+
+ /**
+ * Is this connection right now suspended?
+ */
+ enum MHD_Bool suspended;
+};
+
+
+/**
+ * Obtain information about the given connection.
+ * Use wrapper macro #MHD_connection_get_information() instead of direct use
+ * of this function.
+ *
+ * @param connection what connection to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_ConnectionInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_connection_get_information_sz (struct MHD_Connection *connection,
+ enum MHD_ConnectionInformationType info_type,
+ union MHD_ConnectionInformation *return_value,
+ size_t return_value_size)
+MHD_NONNULL (1,3);
+
+
+/**
+ * Obtain information about the given connection.
+ *
+ * @param connection what connection to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+#define MHD_connection_get_information(connection, \
+ info_type, \
+ return_value) \
+ MHD_connection_get_information_sz ((connection),(info_type),(return_value), \
+ sizeof(union MHD_ConnectionInformation))
+
+
+/**
+ * Information we return about a request.
+ */
+union MHD_RequestInformation
+{
+
+ /**
+ * Connection via which we received the request.
+ */
+ struct MHD_Connection *connection;
+
+ /**
+ * Pointer to client context. Will also be given to
+ * the application in a #MHD_RequestTerminationCallback.
+ */
+ void **request_context;
+
+ /**
+ * HTTP version requested by the client.
+ */
+ const char *http_version;
+
+ /**
+ * HTTP method of the request, as a string. Particularly useful if
+ * #MHD_HTTP_METHOD_UNKNOWN was given.
+ */
+ const char *http_method;
+
+ /**
+ * Size of the client's HTTP header.
+ */
+ size_t header_size;
+
+};
+
+
+/**
+ * Select which member of the `struct RequestInformation`
+ * union is desired to be returned by #MHD_request_get_info().
+ */
+enum MHD_RequestInformationType
+{
+ /**
+ * Return which connection the request is associated with.
+ */
+ MHD_REQUEST_INFORMATION_CONNECTION,
+
+ /**
+ * Returns the client-specific pointer to a `void *` that
+ * is specific to this request.
+ */
+ MHD_REQUEST_INFORMATION_CLIENT_CONTEXT,
+
+ /**
+ * Return the HTTP version string given by the client.
+ * @ingroup request
+ */
+ MHD_REQUEST_INFORMATION_HTTP_VERSION,
+
+ /**
+ * Return the HTTP method used by the request.
+ * @ingroup request
+ */
+ MHD_REQUEST_INFORMATION_HTTP_METHOD,
+
+ /**
+ * Return length of the client's HTTP request header.
+ * @ingroup request
+ */
+ MHD_REQUEST_INFORMATION_HEADER_SIZE
+};
+
+
+/**
+ * Obtain information about the given request.
+ * Use wrapper macro #MHD_request_get_information() instead of direct use
+ * of this function.
+ *
+ * @param request what request to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_RequestInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_request_get_information_sz (struct MHD_Request *request,
+ enum MHD_RequestInformationType info_type,
+ union MHD_RequestInformation *return_value,
+ size_t return_value_size)
+MHD_NONNULL (1,3);
+
+
+/**
+ * Obtain information about the given request.
+ *
+ * @param request what request to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+#define MHD_request_get_information (request, \
+ info_type, \
+ return_value) \
+ MHD_request_get_information_sz ((request), (info_type), (return_value), \
+ sizeof(union MHD_RequestInformation))
+
+
+/**
+ * Values of this enum are used to specify what
+ * information about a daemon is desired.
+ */
+enum MHD_DaemonInformationType
+{
+
+ /**
+ * Request the file descriptor for the listening socket.
+ * No extra arguments should be passed.
+ */
+ MHD_DAEMON_INFORMATION_LISTEN_SOCKET,
+
+ /**
+ * Request the file descriptor for the external epoll.
+ * No extra arguments should be passed.
+ */
+ MHD_DAEMON_INFORMATION_EPOLL_FD,
+
+ /**
+ * Request the number of current connections handled by the daemon.
+ * No extra arguments should be passed.
+ * Note: when using MHD in external polling mode, this type of request
+ * could be used only when #MHD_run()/#MHD_run_from_select is not
+ * working in other thread at the same time.
+ */
+ MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS,
+
+ /**
+ * Request the port number of daemon's listen socket.
+ * No extra arguments should be passed.
+ * Note: if port '0' was specified for #MHD_option_port(), returned
+ * value will be real port number.
+ */
+ MHD_DAEMON_INFORMATION_BIND_PORT
+};
+
+
+/**
+ * Information about an MHD daemon.
+ */
+union MHD_DaemonInformation
+{
+
+ /**
+ * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_SOCKET.
+ */
+ MHD_socket listen_socket;
+
+ /**
+ * Bind port number, returned for #MHD_DAEMON_INFORMATION_BIND_PORT.
+ */
+ uint16_t port;
+
+ /**
+ * epoll FD, returned for #MHD_DAEMON_INFORMATION_EPOLL_FD.
+ */
+ int epoll_fd;
+
+ /**
+ * Number of active connections, for #MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS.
+ */
+ unsigned int num_connections;
+
+};
+
+
+/**
+ * Obtain information about the given daemon.
+ * Use wrapper macro #MHD_daemon_get_information() instead of direct use
+ * of this function.
+ *
+ * @param daemon what daemon to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_DaemonInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
+ enum MHD_DaemonInformationType info_type,
+ union MHD_DaemonInformation *return_value,
+ size_t return_value_size)
+MHD_NONNULL (1,3);
+
+/**
+ * Obtain information about the given daemon.
+ *
+ * @param daemon what daemon to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+#define MHD_daemon_get_information(daemon, \
+ info_type, \
+ return_value) \
+ MHD_daemon_get_information_sz ((daemon), (info_type), (return_value), \
+ sizeof(union MHD_DaemonInformation));
+
+
+/**
+ * Callback for serious error condition. The default action is to print
+ * an error message and `abort()`.
+ *
+ * @param cls user specified value
+ * @param file where the error occurred
+ * @param line where the error occurred
+ * @param reason error detail, may be NULL
+ * @ingroup logging
+ */
+typedef void
+(*MHD_PanicCallback) (void *cls,
+ const char *file,
+ unsigned int line,
+ const char *reason);
+
+
+/**
+ * Sets the global error handler to a different implementation. @a cb
+ * will only be called in the case of typically fatal, serious
+ * internal consistency issues. These issues should only arise in the
+ * case of serious memory corruption or similar problems with the
+ * architecture. While @a cb is allowed to return and MHD will then
+ * try to continue, this is never safe.
+ *
+ * The default implementation that is used if no panic function is set
+ * simply prints an error message and calls `abort()`. Alternative
+ * implementations might call `exit()` or other similar functions.
+ *
+ * @param cb new error handler
+ * @param cls passed to @a cb
+ * @ingroup logging
+ */
+_MHD_EXTERN void
+MHD_set_panic_func (MHD_PanicCallback cb,
+ void *cls);
+
+
+/**
+ * Process escape sequences ('%HH') Updates val in place; the
+ * result should be UTF-8 encoded and cannot be larger than the input.
+ * The result must also still be 0-terminated.
+ *
+ * @param val value to unescape (modified in the process)
+ * @return length of the resulting val (`strlen(val)` may be
+ * shorter afterwards due to elimination of escape sequences)
+ */
+_MHD_EXTERN size_t
+MHD_http_unescape (char *val)
+MHD_NONNULL (1);
+
+
+/**
+ * Types of information about MHD features,
+ * used by #MHD_is_feature_supported().
+ */
+enum MHD_Feature
+{
+ /**
+ * Get whether messages are supported. If supported then in debug
+ * mode messages can be printed to stderr or to external logger.
+ */
+ MHD_FEATURE_MESSAGES = 1,
+
+ /**
+ * Get whether HTTPS is supported. If supported then flag
+ * #MHD_USE_TLS and options #MHD_OPTION_HTTPS_MEM_KEY,
+ * #MHD_OPTION_HTTPS_MEM_CERT, #MHD_OPTION_HTTPS_MEM_TRUST,
+ * #MHD_OPTION_HTTPS_MEM_DHPARAMS, #MHD_OPTION_HTTPS_CRED_TYPE,
+ * #MHD_OPTION_HTTPS_PRIORITIES can be used.
+ */
+ MHD_FEATURE_TLS = 2,
+
+ /**
+ * Get whether option #MHD_OPTION_HTTPS_CERT_CALLBACK is
+ * supported.
+ */
+ MHD_FEATURE_HTTPS_CERT_CALLBACK = 3,
+
+ /**
+ * Get whether IPv6 is supported. If supported then flag
+ * #MHD_USE_IPv6 can be used.
+ */
+ MHD_FEATURE_IPv6 = 4,
+
+ /**
+ * Get whether IPv6 without IPv4 is supported. If not supported
+ * then IPv4 is always enabled in IPv6 sockets and
+ * flag #MHD_USE_DUAL_STACK if always used when #MHD_USE_IPv6 is
+ * specified.
+ */
+ MHD_FEATURE_IPv6_ONLY = 5,
+
+ /**
+ * Get whether `poll()` is supported. If supported then flag
+ * #MHD_USE_POLL can be used.
+ */
+ MHD_FEATURE_POLL = 6,
+
+ /**
+ * Get whether `epoll()` is supported. If supported then Flags
+ * #MHD_USE_EPOLL and
+ * #MHD_USE_EPOLL_INTERNAL_THREAD can be used.
+ */
+ MHD_FEATURE_EPOLL = 7,
+
+ /**
+ * Get whether shutdown on listen socket to signal other
+ * threads is supported. If not supported flag
+ * #MHD_USE_ITC is automatically forced.
+ */
+ MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET = 8,
+
+ /**
+ * Get whether socketpair is used internally instead of pipe to
+ * signal other threads.
+ */
+ MHD_FEATURE_SOCKETPAIR = 9,
+
+ /**
+ * Get whether TCP Fast Open is supported. If supported then
+ * flag #MHD_USE_TCP_FASTOPEN and option
+ * #MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE can be used.
+ */
+ MHD_FEATURE_TCP_FASTOPEN = 10,
+
+ /**
+ * Get whether HTTP Basic authorization is supported. If supported
+ * then functions #MHD_basic_auth_get_username_password and
+ * #MHD_queue_basic_auth_fail_response can be used.
+ */
+ MHD_FEATURE_BASIC_AUTH = 11,
+
+ /**
+ * Get whether HTTP Digest authorization is supported. If
+ * supported then options #MHD_OPTION_DIGEST_AUTH_RANDOM,
+ * #MHD_OPTION_NONCE_NC_SIZE and
+ * #MHD_digest_auth_check() can be used.
+ */
+ MHD_FEATURE_DIGEST_AUTH = 12,
+
+ /**
+ * Get whether postprocessor is supported. If supported then
+ * functions #MHD_create_post_processor(), #MHD_post_process() and
+ * #MHD_destroy_post_processor() can
+ * be used.
+ */
+ MHD_FEATURE_POSTPROCESSOR = 13,
+
+ /**
+ * Get whether password encrypted private key for HTTPS daemon is
+ * supported. If supported then option
+ * ::MHD_OPTION_HTTPS_KEY_PASSWORD can be used.
+ */
+ MHD_FEATURE_HTTPS_KEY_PASSWORD = 14,
+
+ /**
+ * Get whether reading files beyond 2 GiB boundary is supported.
+ * If supported then #MHD_create_response_from_fd(),
+ * #MHD_create_response_from_fd64 #MHD_create_response_from_fd_at_offset()
+ * and #MHD_create_response_from_fd_at_offset64() can be used with sizes and
+ * offsets larger than 2 GiB. If not supported value of size+offset is
+ * limited to 2 GiB.
+ */
+ MHD_FEATURE_LARGE_FILE = 15,
+
+ /**
+ * Get whether MHD set names on generated threads.
+ */
+ MHD_FEATURE_THREAD_NAMES = 16,
+
+ /**
+ * Get whether HTTP "Upgrade" is supported.
+ * If supported then #MHD_ALLOW_UPGRADE, #MHD_upgrade_action() and
+ * #MHD_create_response_for_upgrade() can be used.
+ */
+ MHD_FEATURE_UPGRADE = 17,
+
+ /**
+ * Get whether it's safe to use same FD for multiple calls of
+ * #MHD_create_response_from_fd() and whether it's safe to use single
+ * response generated by #MHD_create_response_from_fd() with multiple
+ * connections at same time.
+ * If #MHD_is_feature_supported() return #MHD_NO for this feature then
+ * usage of responses with same file FD in multiple parallel threads may
+ * results in incorrect data sent to remote client.
+ * It's always safe to use same file FD in multiple responses if MHD
+ * is run in any single thread mode.
+ */
+ MHD_FEATURE_RESPONSES_SHARED_FD = 18,
+
+ /**
+ * Get whether MHD support automatic detection of bind port number.
+ * @sa #MHD_DAEMON_INFO_BIND_PORT
+ */
+ MHD_FEATURE_AUTODETECT_BIND_PORT = 19,
+
+ /**
+ * Get whether MHD support SIGPIPE suppression.
+ * If SIGPIPE suppression is not supported, application must handle
+ * SIGPIPE signal by itself.
+ */
+ MHD_FEATURE_AUTOSUPPRESS_SIGPIPE = 20,
+
+ /**
+ * Get whether MHD use system's sendfile() function to send
+ * file-FD based responses over non-TLS connections.
+ * @note Since v0.9.56
+ */
+ MHD_FEATURE_SENDFILE = 21
+};
+
+
+/**
+ * Get information about supported MHD features.
+ * Indicate that MHD was compiled with or without support for
+ * particular feature. Some features require additional support
+ * by kernel. Kernel support is not checked by this function.
+ *
+ * @param feature type of requested information
+ * @return #MHD_YES if feature is supported by MHD, #MHD_NO if
+ * feature is not supported or feature is unknown.
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_is_feature_supported (enum MHD_Feature feature);
+
+
+/**
+ * What is this request waiting for?
+ */
+enum MHD_RequestEventLoopInfo
+{
+ /**
+ * We are waiting to be able to read.
+ */
+ MHD_EVENT_LOOP_INFO_READ = 0,
+
+ /**
+ * We are waiting to be able to write.
+ */
+ MHD_EVENT_LOOP_INFO_WRITE = 1,
+
+ /**
+ * We are waiting for the application to provide data.
+ */
+ MHD_EVENT_LOOP_INFO_BLOCK = 2,
+
+ /**
+ * We are finished and are awaiting cleanup.
+ */
+ MHD_EVENT_LOOP_INFO_CLEANUP = 3
+};
+
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/microhttpd_tls.h
^
|
@@ -0,0 +1,196 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2018 Christian Grothoff (and other contributing authors)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd_tls.h
+ * @brief interface for TLS plugins of libmicrohttpd
+ * @author Christian Grothoff
+ */
+
+#ifndef MICROHTTPD_TLS_H
+#define MICROHTTPD_TLS_H
+
+#include <microhttpd2.h>
+
+/**
+ * Version of the TLS ABI.
+ */
+#define MHD_TLS_ABI_VERSION 0
+
+/**
+ * Version of the TLS ABI as a string.
+ * Must match #MHD_TLS_ABI_VERSION!
+ */
+#define MHD_TLS_ABI_VERSION_STR "0"
+
+
+/**
+ * Data structure kept per TLS client by the plugin.
+ */
+struct MHD_TLS_ConnectionState;
+
+
+/**
+ * Callback functions to use for TLS operations.
+ */
+struct MHD_TLS_Plugin
+{
+ /**
+ * Closure with plugin's internal state, opaque to MHD.
+ */
+ void *cls;
+
+ /**
+ * Destroy the plugin, we are done with it.
+ */
+ void
+ (*done)(struct MHD_TLS_Plugin *plugin);
+
+ /**
+ * Initialize key and certificate data from memory.
+ *
+ * @param cls the @e cls of this struct
+ * @param mem_key private key (key.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param mem_cert certificate (cert.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param pass passphrase phrase to decrypt 'key.pem', NULL
+ * if @param mem_key is in cleartext already
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+ enum MHD_StatusCode
+ (*init_kcp)(void *cls,
+ const char *mem_key,
+ const char *mem_cert,
+ const char *pass);
+
+
+ /**
+ * Initialize DH parameters.
+ *
+ * @param cls the @e cls of this struct
+ * @param dh parameters to use
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+ enum MHD_StatusCode
+ (*init_dhparams)(void *cls,
+ const char *dh);
+
+
+ /**
+ * Initialize certificate to use for client authentication.
+ *
+ * @param cls the @e cls of this struct
+ * @param mem_trust client certificate
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+ enum MHD_StatusCode
+ (*init_mem_trust)(void *cls,
+ const char *mem_trust);
+
+
+ /**
+ * Function called when we receive a connection and need
+ * to initialize our TLS state for it.
+ *
+ * @param cls the @e cls of this struct
+ * @param ... TBD
+ * @return NULL on error
+ */
+ struct MHD_TLS_ConnectionState *
+ (*setup_connection)(void *cls,
+ ...);
+
+
+ enum MHD_Bool
+ (*handshake)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+
+ enum MHD_Bool
+ (*idle_ready)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+
+ enum MHD_Bool
+ (*update_event_loop_info)(void *cls,
+ struct MHD_TLS_ConnectionState *cs,
+ enum MHD_RequestEventLoopInfo *eli);
+
+ ssize_t
+ (*send)(void *cls,
+ struct MHD_TLS_ConnectionState *cs,
+ const void *buf,
+ size_t buf_size);
+
+
+ ssize_t
+ (*recv)(void *cls,
+ struct MHD_TLS_ConnectionState *cs,
+ void *buf,
+ size_t buf_size);
+
+
+ const char *
+ (*strerror)(void *cls,
+ int ec);
+
+ enum MHD_Bool
+ (*check_record_pending)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+ enum MHD_Bool
+ (*shutdown_connection)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+
+ void
+ (*teardown_connection)(void *cls,
+ struct MHD_TLS_ConnectionState *cs);
+
+ /**
+ * TODO: More functions here....
+ */
+
+};
+
+
+/**
+ * Signature of the initialization function each TLS plugin must
+ * export.
+ *
+ * @param ciphers desired cipher suite
+ * @return NULL on errors (in particular, invalid cipher suite)
+ */
+typedef struct MHD_TLS_Plugin *
+(*MHD_TLS_PluginInit) (const char *ciphers);
+
+
+/**
+ * Define function to be exported from the TLS plugin.
+ *
+ * @a body function body that receives `ciphers` argument
+ * and must return the plugin API, or NULL on error.
+ */
+#define MHD_TLS_INIT(body) \
+ struct MHD_TLS_Plugin * \
+ MHD_TLS_init_ ## MHD_TLS_ABI_VERSION (const char *ciphers) \ \
+ { body }
+
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/include/platform.h
^
|
@@ -94,7 +94,7 @@
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#ifndef WIN32_LEAN_AND_MEAN
/* Do not include unneeded parts of W32 headers. */
#define WIN32_LEAN_AND_MEAN 1
@@ -103,28 +103,28 @@
#include <ws2tcpip.h>
#endif /* _WIN32 && !__CYGWIN__ */
-#if defined(__CYGWIN__) && !defined(_SYS_TYPES_FD_SET)
+#if defined(__CYGWIN__) && ! defined(_SYS_TYPES_FD_SET)
/* Do not define __USE_W32_SOCKETS under Cygwin! */
#error Cygwin with winsock fd_set is not supported
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define sleep(seconds) ((SleepEx((seconds)*1000, 1)==0)?0:(seconds))
-#define usleep(useconds) ((SleepEx((useconds)/1000, 1)==0)?0:-1)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+#define sleep(seconds) ((SleepEx ((seconds) * 1000, 1)==0) ? 0 : (seconds))
+#define usleep(useconds) ((SleepEx ((useconds) / 1000, 1)==0) ? 0 : -1)
#endif
-#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
+#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
#define _SSIZE_T_DEFINED
typedef intptr_t ssize_t;
#endif /* !_SSIZE_T_DEFINED */
-#ifndef _WIN32
+#if ! defined(_WIN32) || defined(__CYGWIN__)
typedef time_t _MHD_TIMEVAL_TV_SEC_TYPE;
-#else /* _WIN32 */
+#else /* _WIN32 && ! __CYGWIN__ */
typedef long _MHD_TIMEVAL_TV_SEC_TYPE;
-#endif /* _WIN32 */
+#endif /* _WIN32 && ! __CYGWIN__ */
-#if !defined(IPPROTO_IPV6) && defined(_MSC_FULL_VER) && _WIN32_WINNT >= 0x0501
+#if ! defined(IPPROTO_IPV6) && defined(_MSC_FULL_VER) && _WIN32_WINNT >= 0x0501
/* VC use IPPROTO_IPV6 as part of enum */
#define IPPROTO_IPV6 IPPROTO_IPV6
#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/Makefile.am
^
|
@@ -0,0 +1,182 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/include \
+ -I$(top_srcdir)/src/lib
+
+AM_CFLAGS = $(HIDDEN_VISIBILITY_CFLAGS)
+
+# Call "libmicrohttpd2" for now, but only while under
+# development. Once we have 'compat' working, this should be changed!
+noinst_LTLIBRARIES = \
+ libmicrohttpd2.la
+
+noinst_DATA =
+MOSTLYCLEANFILES =
+
+if W32_SHARED_LIB_EXP
+W32_MHD_LIB_LDFLAGS = -Wl,--output-def,$(lt_cv_objdir)/libmicrohttpd2.def -XCClinker -static-libgcc
+noinst_DATA += $(lt_cv_objdir)/libmicrohttpd2.lib $(lt_cv_objdir)/libmicrohttpd2.def $(lt_cv_objdir)/libmicrohttpd2.exp
+MOSTLYCLEANFILES += $(lt_cv_objdir)/libmicrohttpd2.lib $(lt_cv_objdir)/libmicrohttpd2.def $(lt_cv_objdir)/libmicrohttpd2.exp
+
+$(lt_cv_objdir)/libmicrohttpd2.def: libmicrohttpd2.la
+
+$(lt_cv_objdir)/libmicrohttpd2.exp: $(lt_cv_objdir)/libmicrohttpd2.lib
+
+$(lt_cv_objdir)/libmicrohttpd2.lib: $(lt_cv_objdir)/libmicrohttpd2.def libmicrohttpd2.la $(libmicrohttpd2_la_OBJECTS)
+if USE_MS_LIB_TOOL
+ @echo Creating $@ and libmicrohttpd2.exp by $(MS_LIB_TOOL)... && \
+ dll_name=`$(EGREP) -o dlname=\'.+\' libmicrohttpd2.la` && \
+ dll_name=$${dll_name#*\'} && dll_name=$${dll_name%\'} && test -n "$$dll_name" && \
+ echo Creating $$dll_name by $(MS_LIB_TOOL).. && cd "$(lt_cv_objdir)" && \
+ $(MS_LIB_TOOL) -def:libmicrohttpd2.def -name:$$dll_name -out:libmicrohttpd2.lib $(libmicrohttpd2_la_OBJECTS:.lo=.o) && cd ..
+else
+ @echo Creating $@ and libmicrohttpd2.exp by $(DLLTOOL)... && \
+ dll_name=`$(EGREP) -o dlname=\'.+\' libmicrohttpd2.la` && \
+ dll_name=$${dll_name#*\'} && dll_name=$${dll_name%\'} && test -n "$$dll_name" && \
+ echo Creating $$dll_name by $(DLLTOOL).. && cd "$(lt_cv_objdir)" && \
+ $(DLLTOOL) -d ./libmicrohttpd2.def -D $$dll_name -l libmicrohttpd2.lib $(libmicrohttpd2_la_OBJECTS:.lo=.o) -e ./libmicrohttpd2.exp && cd .. &&\
+ echo Created libmicrohttpd2.exp and libmicrohttpd2.lib.
+endif
+else
+ W32_MHD_LIB_LDFLAGS =
+endif
+
+if W32_STATIC_LIB
+noinst_DATA += $(lt_cv_objdir)/libmicrohttpd2-static.lib
+MOSTLYCLEANFILES += $(lt_cv_objdir)/libmicrohttpd2-static.lib
+
+$(lt_cv_objdir)/libmicrohttpd2-static.lib: libmicrohttpd2.la $(libmicrohttpd2_la_OBJECTS)
+if USE_MS_LIB_TOOL
+ $(MS_LIB_TOOL) -out:$@ $(libmicrohttpd2_la_OBJECTS:.lo=.o)
+else
+ cp $(lt_cv_objdir)/libmicrohttpd2.a $@
+endif
+endif
+
+
+libmicrohttpd2_la_SOURCES = \
+ action_continue.c \
+ action_from_response.c \
+ action_parse_post.c \
+ action_process_upload.c \
+ action_suspend.c \
+ connection_add.c connection_add.h \
+ connection_call_handlers.c connection_call_handlers.h \
+ connection_cleanup.c connection_cleanup.h \
+ connection_close.c connection_close.h \
+ connection_finish_forward.c connection_finish_forward.h \
+ connection_info.c \
+ connection_options.c \
+ connection_update_last_activity.c connection_update_last_activity.h \
+ daemon_close_all_connections.c daemon_close_all_connections.h \
+ daemon_create.c \
+ daemon_destroy.c \
+ daemon_epoll.c daemon_epoll.h \
+ daemon_get_timeout.c \
+ daemon_info.c \
+ daemon_ip_limit.c daemon_ip_limit.h \
+ daemon_options.c \
+ daemon_poll.c daemon_poll.h \
+ daemon_run.c \
+ daemon_select.c daemon_select.h \
+ daemon_start.c \
+ daemon_quiesce.c \
+ init.c init.h \
+ internal.c internal.h \
+ memorypool.c memorypool.h \
+ mhd_assert.h \
+ mhd_byteorder.h \
+ mhd_compat.c mhd_compat.h \
+ mhd_itc.c mhd_itc.h mhd_itc_types.h \
+ mhd_limits.h \
+ mhd_locks.h \
+ mhd_mono_clock.c mhd_mono_clock.h \
+ mhd_str.c mhd_str.h \
+ mhd_sockets.c mhd_sockets.h \
+ mhd_threads.c mhd_threads.h \
+ response.c \
+ response_for_upgrade.c \
+ response_from_buffer.c \
+ response_from_callback.c \
+ response_from_fd.c \
+ response_options.c \
+ reason_phrase.c \
+ request.c \
+ request_info.c \
+ request_resume.c \
+ request_resume.h \
+ sysfdsetsize.c sysfdsetsize.h \
+ upgrade_process.c upgrade_process.h \
+ panic.c \
+ version.c
+
+libmicrohttpd2_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) \
+ -DBUILDING_MHD_LIB=1
+libmicrohttpd2_la_CFLAGS = \
+ $(AM_CFLAGS) $(MHD_LIB_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+libmicrohttpd2_la_LDFLAGS = \
+ $(MHD_LIB_LDFLAGS) \
+ $(W32_MHD_LIB_LDFLAGS) $(MHD_TLS_LIB_LDFLAGS) \
+ -version-info 0:0:0 # FIXME: fix once closer to release...
+if MHD_HAVE_TLS_PLUGIN
+libmicrohttpd2_la_LDFLAGS += \
+ -ldl
+endif
+
+libmicrohttpd2_la_LIBADD = \
+ $(MHD_LIBDEPS) $(MHD_TLS_LIBDEPS)
+
+if HAVE_W32
+MHD_DLL_RES_SRC = ../microhttpd/microhttpd_dll_res.rc
+MHD_DLL_RES_LO = libmicrohttpd2_la-$(MHD_DLL_RES_SRC:.rc=.lo)
+
+EXTRA_libmicrohttpd2_la_DEPENDENCIES = $(MHD_DLL_RES_LO)
+libmicrohttpd2_la_LIBADD += $(MHD_DLL_RES_LO)
+
+# General rule is not required, but keep it just in case
+.rc.lo:
+ $(LIBTOOL) $(AM_V_lt) --tag=RC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(RC) $(RCFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $< -o $@
+
+# To add dll resource only to .dll file and exclude it form static
+# lib, a little trick was used. Allow libtool to create file.lo,
+# file.o and .libs/file.lo, .libs/file.o files, then overwrite file.o
+# by empty object generated from empty c-file. Later libtool will
+# use .libs/file.o for shared lib and empty file.o for static lib.
+# This implementation is based on trick found in liblzma.
+# Note: windres does not understand '-isystem' flag, so all
+# possible '-isystem' flags are replaced by simple '-I' flags.
+$(MHD_DLL_RES_LO): $(MHD_DLL_RES_SRC)
+ RC_CPP_FLAGS=" $(DEFAULT_INCLUDES) $(INCLUDES) $(libmicrohttpd2_la_CPPFLAGS) $(CPPFLAGS) " && \
+ $(LIBTOOL) $(AM_V_lt) --tag=RC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(RC) $(RCFLAGS) $(DEFS) $${RC_CPP_FLAGS// -isystem / -I } $< -o $@ && \
+ echo > $@-empty.c && $(CC) $(AM_CFLAGS) $(CFLAGS) -c $@-empty.c -o $(@:.lo=.o) && rm -f $@-empty.c
+endif
+
+if USE_COVERAGE
+ AM_CFLAGS += --coverage
+endif
+
+if !MHD_HAVE_TSEARCH
+libmicrohttpd2_la_SOURCES += \
+ tsearch.c tsearch.h
+endif
+
+# TBD!
+if HAVE_POSTPROCESSOR
+#libmicrohttpd2_la_SOURCES += \
+# postprocessor.c
+endif
+
+# TBD!
+if ENABLE_DAUTH
+#libmicrohttpd2_la_SOURCES += \
+# digestauth.c \
+# md5.c md5.h
+endif
+
+# TBD!
+if ENABLE_BAUTH
+#libmicrohttpd2_la_SOURCES += \
+# basicauth.c \
+# base64.c base64.h
+endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/action_continue.c
^
|
@@ -0,0 +1,65 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/action_continue.c
+ * @brief implementation of MHD_action_continue()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * The continue action is being run. Continue
+ * handling the upload.
+ *
+ * @param cls NULL
+ * @param request the request to apply the action to
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+cont_action (void *cls,
+ struct MHD_Request *request)
+{
+ (void) cls;
+ (void) request;
+ /* not sure yet, but this function body may
+ just legitimately stay empty... */
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Action telling MHD to continue processing the upload.
+ *
+ * @return action operation, never NULL
+ */
+const struct MHD_Action *
+MHD_action_continue (void)
+{
+ static struct MHD_Action acont = {
+ .action = &cont_action,
+ .action_cls = NULL
+ };
+
+ return &acont;
+}
+
+
+/* end of action_continue.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/action_from_response.c
^
|
@@ -0,0 +1,132 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/action_from_response.c
+ * @brief implementation of #MHD_action_from_response()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_call_handlers.h"
+
+
+/**
+ * A response was given as the desired action for a @a request.
+ * Queue the response for the request.
+ *
+ * @param cls the `struct MHD_Response`
+ * @param request the request we are processing
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+response_action (void *cls,
+ struct MHD_Request *request)
+{
+ struct MHD_Response *response = cls;
+ struct MHD_Daemon *daemon = request->daemon;
+
+ /* If daemon was shut down in parallel,
+ * response will be aborted now or on later stage. */
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+
+#ifdef UPGRADE_SUPPORT
+ if ( (NULL != response->upgrade_handler) &&
+ daemon->disallow_upgrade)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED,
+ _ (
+ "Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
+#endif
+ return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED;
+ }
+#endif /* UPGRADE_SUPPORT */
+ request->response = response;
+#if defined(_MHD_HAVE_SENDFILE)
+ if ( (-1 == response->fd)
+#if HTTPS_SUPPORT
+ || (NULL != daemon->tls_api)
+#endif
+ )
+ request->resp_sender = MHD_resp_sender_std;
+ else
+ request->resp_sender = MHD_resp_sender_sendfile;
+#endif /* _MHD_HAVE_SENDFILE */
+
+ if ( (MHD_METHOD_HEAD == request->method) ||
+ (MHD_HTTP_OK > response->status_code) ||
+ (MHD_HTTP_NO_CONTENT == response->status_code) ||
+ (MHD_HTTP_NOT_MODIFIED == response->status_code) )
+ {
+ /* if this is a "HEAD" request, or a status code for
+ which a body is not allowed, pretend that we
+ have already sent the full message body. */
+ request->response_write_position = response->total_size;
+ }
+ if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
+ ( (MHD_METHOD_POST == request->method) ||
+ (MHD_METHOD_PUT == request->method) ) )
+ {
+ /* response was queued "early", refuse to read body / footers or
+ further requests! */
+ request->connection->read_closed = true;
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ }
+ if (! request->in_idle)
+ (void) MHD_request_handle_idle_ (request);
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Converts a @a response to an action. If @a consume
+ * is set, the reference to the @a response is consumed
+ * by the conversion. If @a consume is #MHD_NO, then
+ * the response can be converted to actions in the future.
+ * However, the @a response is frozen by this step and
+ * must no longer be modified (i.e. by setting headers).
+ *
+ * @param response response to convert, not NULL
+ * @param destroy_after_use should the response object be consumed?
+ * @return corresponding action, never returns NULL
+ *
+ * Implementation note: internally, this is largely just
+ * a cast (and possibly an RC increment operation),
+ * as a response *is* an action. As no memory is
+ * allocated, this operation cannot fail.
+ */
+_MHD_EXTERN const struct MHD_Action *
+MHD_action_from_response (struct MHD_Response *response,
+ enum MHD_Bool destroy_after_use)
+{
+ response->action.action = &response_action;
+ response->action.action_cls = response;
+ if (! destroy_after_use)
+ {
+ MHD_mutex_lock_chk_ (&response->mutex);
+ response->reference_count++;
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ }
+ return &response->action;
+}
+
+
+/* end of action_from_response */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/action_parse_post.c
^
|
@@ -0,0 +1,61 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/action_parse_post.c
+ * @brief implementation of MHD_action_parse_post()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Create an action that parses a POST request.
+ *
+ * This action can be used to (incrementally) parse the data portion
+ * of a POST request. Note that some buggy browsers fail to set the
+ * encoding type. If you want to support those, you may have to call
+ * #MHD_set_connection_value with the proper encoding type before
+ * returning this action (if no supported encoding type is detected,
+ * returning this action will cause a bad request to be returned to
+ * the client).
+ *
+ * @param buffer_size maximum number of bytes to use for
+ * internal buffering (used only for the parsing,
+ * specifically the parsing of the keys). A
+ * tiny value (256-1024) should be sufficient.
+ * Do NOT use a value smaller than 256. For good
+ * performance, use 32 or 64k (i.e. 65536).
+ * @param iter iterator to be called with the parsed data,
+ * Must NOT be NULL.
+ * @param iter_cls first argument to @a iter
+ * @return NULL on error (out of memory, unsupported encoding),
+ * otherwise a PP handle
+ * @ingroup request
+ */
+const struct MHD_Action *
+MHD_action_parse_post (size_t buffer_size,
+ MHD_PostDataIterator iter,
+ void *iter_cls)
+{
+ return NULL; /* not yet implemented */
+}
+
+
+/* end of action_parse_post.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/action_process_upload.c
^
|
@@ -0,0 +1,92 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/action_process_upload.c
+ * @brief implementation of MHD_action_process_upload()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Internal details about an upload action.
+ */
+struct UploadAction
+{
+ /**
+ * An upload action is an action. This field
+ * must come first!
+ */
+ struct MHD_Action action;
+
+ MHD_UploadCallback uc;
+
+ void *uc_cls;
+
+};
+
+
+/**
+ * The application wants to process uploaded data for
+ * the given request. Do it!
+ *
+ * @param cls the `struct UploadAction` with the
+ * function we are to call for upload data
+ * @param request the request for which we are to process
+ * upload data
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+upload_action (void *cls,
+ struct MHD_Request *request)
+{
+ struct UploadAction *ua = cls;
+
+ (void) ua;
+ // FIXME: implement!
+ return -1;
+}
+
+
+/**
+ * Create an action that handles an upload.
+ *
+ * @param uc function to call with uploaded data
+ * @param uc_cls closure for @a uc
+ * @return NULL on error (out of memory)
+ * @ingroup action
+ */
+const struct MHD_Action *
+MHD_action_process_upload (MHD_UploadCallback uc,
+ void *uc_cls)
+{
+ struct UploadAction *ua;
+
+ if (NULL == (ua = malloc (sizeof (struct UploadAction))))
+ return NULL;
+ ua->action.action = &upload_action;
+ ua->action.action_cls = ua;
+ ua->uc = uc;
+ ua->uc_cls = uc_cls;
+ return &ua->action;
+}
+
+
+/* end of action_process_upload.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/action_suspend.c
^
|
@@ -0,0 +1,138 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/action_suspend.c
+ * @brief implementation of MHD_action_suspend()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * The suspend action is being run. Suspend handling
+ * of the given request.
+ *
+ * @param cls NULL
+ * @param request the request to apply the action to
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+suspend_action (void *cls,
+ struct MHD_Request *request)
+{
+ (void) cls;
+ struct MHD_Connection *connection = request->connection;
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ if (connection->resuming)
+ {
+ /* suspending again while we didn't even complete resuming yet */
+ connection->resuming = false;
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ return MHD_SC_OK;
+ }
+ if (daemon->threading_mode != MHD_TM_THREAD_PER_CONNECTION)
+ {
+ if (connection->connection_timeout ==
+ daemon->connection_default_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ DLL_remove (daemon->connections_head,
+ daemon->connections_tail,
+ connection);
+ mhd_assert (! connection->suspended);
+ DLL_insert (daemon->suspended_connections_head,
+ daemon->suspended_connections_tail,
+ connection);
+ connection->suspended = true;
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
+ {
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ connection->socket_fd,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
+ }
+#endif
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Suspend handling of network data for a given request. This can
+ * be used to dequeue a request from MHD's event loop for a while.
+ *
+ * If you use this API in conjunction with a internal select or a
+ * thread pool, you must set the option #MHD_USE_ITC to
+ * ensure that a resumed request is immediately processed by MHD.
+ *
+ * Suspended requests continue to count against the total number of
+ * requests allowed (per daemon, as well as per IP, if such limits
+ * are set). Suspended requests will NOT time out; timeouts will
+ * restart when the request handling is resumed. While a
+ * request is suspended, MHD will not detect disconnects by the
+ * client.
+ *
+ * The only safe time to suspend a request is from either a
+ * #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a
+ * #MHD_RequestfetchResponseCallback. Suspending a request
+ * at any other time will cause an assertion failure.
+ *
+ * Finally, it is an API violation to call #MHD_daemon_stop() while
+ * having suspended requests (this will at least create memory and
+ * socket leaks or lead to undefined behavior). You must explicitly
+ * resume all requests before stopping the daemon.
+ *
+ * @return action to cause a request to be suspended.
+ */
+const struct MHD_Action *
+MHD_action_suspend (void)
+{
+ static const struct MHD_Action suspend = {
+ .action = &suspend_action,
+ .action_cls = NULL
+ };
+
+ return &suspend;
+}
+
+
+/* end of action_suspend.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/base64.c
^
|
@@ -0,0 +1,60 @@
+/*
+ * This code implements the BASE64 algorithm.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * @file base64.c
+ * @brief This code implements the BASE64 algorithm
+ * @author Matthieu Speder
+ */
+#include "base64.h"
+
+static const char base64_digits[] =
+{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+char *
+BASE64Decode (const char*src)
+{
+ size_t in_len = strlen (src);
+ char*dest;
+ char*result;
+
+ if (in_len % 4)
+ {
+ /* Wrong base64 string length */
+ return NULL;
+ }
+ result = dest = malloc (in_len / 4 * 3 + 1);
+ if (NULL == result)
+ return NULL; /* out of memory */
+ while (*src)
+ {
+ char a = base64_digits[(unsigned char) *(src++)];
+ char b = base64_digits[(unsigned char) *(src++)];
+ char c = base64_digits[(unsigned char) *(src++)];
+ char d = base64_digits[(unsigned char) *(src++)];
+ *(dest++) = (a << 2) | ((b & 0x30) >> 4);
+ if (c == (char) -1)
+ break;
+ *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
+ if (d == (char) -1)
+ break;
+ *(dest++) = ((c & 0x03) << 6) | d;
+ }
+ *dest = 0;
+ return result;
+}
+
+
+/* end of base64.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/base64.h
^
|
@@ -0,0 +1,17 @@
+/*
+ * This code implements the BASE64 algorithm.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * @file base64.c
+ * @brief This code implements the BASE64 algorithm
+ * @author Matthieu Speder
+ */
+#ifndef BASE64_H
+#define BASE64_H
+
+#include "platform.h"
+
+char *
+BASE64Decode (const char*src);
+
+#endif /* !BASE64_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_add.c
^
|
@@ -0,0 +1,1140 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_add.c
+ * @brief functions to add connection to our active set
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_add.h"
+#include "connection_call_handlers.h"
+#include "connection_close.h"
+#include "connection_finish_forward.h"
+#include "connection_update_last_activity.h"
+#include "daemon_ip_limit.h"
+#include "daemon_select.h"
+#include "daemon_poll.h"
+#include "mhd_sockets.h"
+
+
+#ifdef UPGRADE_SUPPORT
+/**
+ * Main function of the thread that handles an individual connection
+ * after it was "upgraded" when #MHD_USE_THREAD_PER_CONNECTION is set.
+ * @remark To be called only from thread that process
+ * connection's recv(), send() and response.
+ *
+ * @param con the connection this thread will handle
+ */
+static void
+thread_main_connection_upgrade (struct MHD_Connection *con)
+{
+#ifdef HTTPS_SUPPORT
+ struct MHD_Daemon *daemon = con->daemon;
+
+ /* Here, we need to bi-directionally forward
+ until the application tells us that it is done
+ with the socket; */
+ if ( (NULL != daemon->tls_api) &&
+ (MHD_ELS_POLL != daemon->event_loop_syscall) )
+ {
+ MHD_daemon_upgrade_connection_with_select_ (con);
+ }
+#ifdef HAVE_POLL
+ else if (NULL != daemon->tls_api)
+ {
+ MHD_daemon_upgrade_connection_with_poll_ (con);
+ }
+#endif
+ /* end HTTPS */
+#endif /* HTTPS_SUPPORT */
+ /* TLS forwarding was finished. Cleanup socketpair. */
+ MHD_connection_finish_forward_ (con);
+ /* Do not set 'urh->clean_ready' yet as 'urh' will be used
+ * in connection thread for a little while. */
+}
+
+
+#endif /* UPGRADE_SUPPORT */
+
+
+/**
+ * Main function of the thread that handles an individual
+ * connection when #MHD_USE_THREAD_PER_CONNECTION is set.
+ *
+ * @param data the `struct MHD_Connection` this thread will handle
+ * @return always 0
+ */
+static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
+thread_main_handle_connection (void *data)
+{
+ struct MHD_Connection *con = data;
+ struct MHD_Daemon *daemon = con->daemon;
+ int num_ready;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxsock;
+ struct timeval tv;
+ struct timeval *tvp;
+ time_t now;
+#if WINDOWS
+#ifdef HAVE_POLL
+ int extra_slot;
+#endif /* HAVE_POLL */
+#define EXTRA_SLOTS 1
+#else /* !WINDOWS */
+#define EXTRA_SLOTS 0
+#endif /* !WINDOWS */
+#ifdef HAVE_POLL
+ struct pollfd p[1 + EXTRA_SLOTS];
+#endif
+#undef EXTRA_SLOTS
+#ifdef HAVE_POLL
+ const bool use_poll = (MHD_ELS_POLL == daemon->event_loop_syscall);
+#else /* ! HAVE_POLL */
+ const bool use_poll = false;
+#endif /* ! HAVE_POLL */
+ bool was_suspended = false;
+
+ MHD_thread_init_ (&con->pid);
+
+ while ( (! daemon->shutdown) &&
+ (MHD_REQUEST_CLOSED != con->request.state) )
+ {
+ const time_t timeout = daemon->connection_default_timeout;
+#ifdef UPGRADE_SUPPORT
+ struct MHD_UpgradeResponseHandle *const urh = con->request.urh;
+#else /* ! UPGRADE_SUPPORT */
+ static const void *const urh = NULL;
+#endif /* ! UPGRADE_SUPPORT */
+
+ if ( (con->suspended) &&
+ (NULL == urh) )
+ {
+ /* Connection was suspended, wait for resume. */
+ was_suspended = true;
+ if (! use_poll)
+ {
+ FD_ZERO (&rs);
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ NULL,
+ FD_SETSIZE))
+ {
+ #ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
+ _ ("Failed to add FD to fd_set.\n"));
+ #endif
+ goto exit;
+ }
+ if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
+ &rs,
+ NULL,
+ NULL,
+ NULL))
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_SELECT_ERROR,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ }
+#ifdef HAVE_POLL
+ else /* use_poll */
+ {
+ p[0].events = POLLIN;
+ p[0].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[0].revents = 0;
+ if (0 > MHD_sys_poll_ (p,
+ 1,
+ -1))
+ {
+ if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_POLL_ERROR,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ break;
+ }
+ }
+#endif /* HAVE_POLL */
+ MHD_itc_clear_ (daemon->itc);
+ continue; /* Check again for resume. */
+ } /* End of "suspended" branch. */
+
+ if (was_suspended)
+ {
+ MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */
+ /* Process response queued during suspend and update states. */
+ MHD_request_handle_idle_ (&con->request);
+ was_suspended = false;
+ }
+
+ tvp = NULL;
+
+ if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info)
+#ifdef HTTPS_SUPPORT
+ || ( (con->tls_read_ready) &&
+ (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) )
+#endif /* HTTPS_SUPPORT */
+ )
+ {
+ /* do not block: more data may be inside of TLS buffers waiting or
+ * application must provide response data */
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ if ( (NULL == tvp) &&
+ (timeout > 0) )
+ {
+ now = MHD_monotonic_sec_counter ();
+ if (now - con->last_activity > timeout)
+ tv.tv_sec = 0;
+ else
+ {
+ const time_t seconds_left = timeout - (now - con->last_activity);
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+ tv.tv_sec = seconds_left;
+#else /* _WIN32 && !__CYGWIN__ */
+ if (seconds_left > TIMEVAL_TV_SEC_MAX)
+ tv.tv_sec = TIMEVAL_TV_SEC_MAX;
+ else
+ tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
+#endif /* _WIN32 && ! __CYGWIN__ */
+ }
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ if (! use_poll)
+ {
+ /* use select */
+ bool err_state = false;
+
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ maxsock = MHD_INVALID_SOCKET;
+ switch (con->request.event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &ws,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &es,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* how did we get here!? */
+ goto exit;
+ }
+#if WINDOWS
+ if (MHD_ITC_IS_VALID_ (daemon->itc) )
+ {
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = 1;
+ }
+#endif
+ if (err_state)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
+ _ ("Failed to add FD to fd_set.\n"));
+#endif
+ goto exit;
+ }
+
+ num_ready = MHD_SYS_select_ (maxsock + 1,
+ &rs,
+ &ws,
+ &es,
+ tvp);
+ if (num_ready < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_SELECT_ERROR,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+#if WINDOWS
+ /* Clear ITC before other processing so additional
+ * signals will trigger select() again */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
+ &rs)) )
+ MHD_itc_clear_ (daemon->itc);
+#endif
+ if (MHD_NO ==
+ MHD_connection_call_handlers_ (con,
+ FD_ISSET (con->socket_fd,
+ &rs),
+ FD_ISSET (con->socket_fd,
+ &ws),
+ FD_ISSET (con->socket_fd,
+ &es)) )
+ goto exit;
+ }
+#ifdef HAVE_POLL
+ else
+ {
+ /* use poll */
+ memset (&p,
+ 0,
+ sizeof (p));
+ p[0].fd = con->socket_fd;
+ switch (con->request.event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* how did we get here!? */
+ goto exit;
+ }
+#if WINDOWS
+ extra_slot = 0;
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[1].events |= POLLIN;
+ p[1].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[1].revents = 0;
+ extra_slot = 1;
+ }
+#endif
+ if (MHD_sys_poll_ (p,
+#if WINDOWS
+ 1 + extra_slot,
+#else
+ 1,
+#endif
+ (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
+ {
+ if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_POLL_ERROR,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ break;
+ }
+#if WINDOWS
+ /* Clear ITC before other processing so additional
+ * signals will trigger poll() again */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
+ MHD_itc_clear_ (daemon->itc);
+#endif
+ if (MHD_NO ==
+ MHD_connection_call_handlers_ (con,
+ (0 != (p[0].revents & POLLIN)),
+ (0 != (p[0].revents & POLLOUT)),
+ (0 != (p[0].revents & (POLLERR
+ |
+ MHD_POLL_REVENTS_ERR_DISC))) ))
+ goto exit;
+ }
+#endif
+#ifdef UPGRADE_SUPPORT
+ if (MHD_REQUEST_UPGRADE == con->request.state)
+ {
+ /* Normal HTTP processing is finished,
+ * notify application. */
+ if (NULL != con->request.response->termination_cb)
+ con->request.response->termination_cb
+ (con->request.response->termination_cb_cls,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK,
+ con->request.client_context);
+ thread_main_connection_upgrade (con);
+ /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
+
+ /* "Upgraded" data will not be used in this thread from this point. */
+ con->request.urh->clean_ready = true;
+ /* If 'urh->was_closed' set to true, connection will be
+ * moved immediately to cleanup list. Otherwise connection
+ * will stay in suspended list until 'urh' will be marked
+ * with 'was_closed' by application. */
+ MHD_request_resume (&con->request);
+
+ /* skip usual clean up */
+ return (MHD_THRD_RTRN_TYPE_) 0;
+ }
+#endif /* UPGRADE_SUPPORT */
+ }
+#if DEBUG_CLOSE
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_THREAD_TERMINATING,
+ _ ("Processing thread terminating. Closing connection.\n"));
+#endif
+#endif
+ if (MHD_REQUEST_CLOSED != con->request.state)
+ MHD_connection_close_ (con,
+ (daemon->shutdown) ?
+ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+ MHD_request_handle_idle_ (&con->request);
+exit:
+ if (NULL != con->request.response)
+ {
+ MHD_response_queue_for_destroy (con->request.response);
+ con->request.response = NULL;
+ }
+
+ if (MHD_INVALID_SOCKET != con->socket_fd)
+ {
+ shutdown (con->socket_fd,
+ SHUT_WR);
+ /* 'socket_fd' can be used in other thread to signal shutdown.
+ * To avoid data races, do not close socket here. Daemon will
+ * use more connections only after cleanup anyway. */
+ }
+ return (MHD_THRD_RTRN_TYPE_) 0;
+}
+
+
+/**
+ * Callback for receiving data from the socket.
+ *
+ * @param connection the MHD connection structure
+ * @param other where to write received data to
+ * @param i maximum size of other (in bytes)
+ * @return positive value for number of bytes actually received or
+ * negative value for error number MHD_ERR_xxx_
+ */
+static ssize_t
+recv_param_adapter (struct MHD_Connection *connection,
+ void *other,
+ size_t i)
+{
+ ssize_t ret;
+
+ if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
+ (MHD_REQUEST_CLOSED == connection->request.state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+ if (i > MHD_SCKT_SEND_MAX_SIZE_)
+ i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
+
+ ret = MHD_recv_ (connection->socket_fd,
+ other,
+ i);
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* Got EAGAIN --- no longer read-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
+ return MHD_ERR_CONNRESET_;
+ /* Treat any other error as hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#ifdef EPOLL_SUPPORT
+ else if (i > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
+#endif /* EPOLL_SUPPORT */
+ return ret;
+}
+
+
+/**
+ * Callback for writing data to the socket.
+ *
+ * @param connection the MHD connection structure
+ * @param other data to write
+ * @param i number of bytes to write
+ * @return positive value for number of bytes actually sent or
+ * negative value for error number MHD_ERR_xxx_
+ */
+static ssize_t
+send_param_adapter (struct MHD_Connection *connection,
+ const void *other,
+ size_t i)
+{
+ ssize_t ret;
+
+ if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
+ (MHD_REQUEST_CLOSED == connection->request.state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+ if (i > MHD_SCKT_SEND_MAX_SIZE_)
+ i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
+
+ ret = MHD_send_ (connection->socket_fd,
+ other,
+ i);
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* EAGAIN --- no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
+ return MHD_ERR_CONNRESET_;
+ /* Treat any other error as hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#ifdef EPOLL_SUPPORT
+ else if (i > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return ret;
+}
+
+
+/**
+ * Add another client connection to the set of connections
+ * managed by MHD. This API is usually not needed (since
+ * MHD will accept inbound connections on the server socket).
+ * Use this API in special cases, for example if your HTTP
+ * server is behind NAT and needs to connect out to the
+ * HTTP client.
+ *
+ * The given client socket will be managed (and closed!) by MHD after
+ * this call and must no longer be used directly by the application
+ * afterwards.
+ *
+ * @param daemon daemon that manages the connection
+ * @param client_socket socket to manage (MHD will expect
+ * to receive an HTTP request from this socket next).
+ * @param addr IP address of the client
+ * @param addrlen number of bytes in @a addr
+ * @param external_add perform additional operations needed due
+ * to the application calling us directly
+ * @param non_blck indicate that socket in non-blocking mode
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+internal_add_connection (struct MHD_Daemon *daemon,
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen,
+ bool external_add,
+ bool non_blck)
+{
+ enum MHD_StatusCode sc;
+ struct MHD_Connection *connection;
+ int eno = 0;
+
+ /* Direct add to master daemon could happen only with "external" add mode. */
+ mhd_assert ( (NULL == daemon->worker_pool) ||
+ (external_add) );
+ if ( (external_add) &&
+ (NULL != daemon->worker_pool) )
+ {
+ unsigned int i;
+
+ /* have a pool, try to find a pool with capacity; we use the
+ socket as the initial offset into the pool for load
+ balancing */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
+ {
+ struct MHD_Daemon *const worker =
+ &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
+ if (worker->connections < worker->global_connection_limit)
+ return internal_add_connection (worker,
+ client_socket,
+ addr,
+ addrlen,
+ true,
+ non_blck);
+ }
+ /* all pools are at their connection limit, must refuse */
+ MHD_socket_close_chk_ (client_socket);
+#if ENFILE
+ errno = ENFILE;
+#endif
+ return MHD_SC_LIMIT_CONNECTIONS_REACHED;
+ }
+
+ if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket,
+ NULL)) &&
+ (MHD_ELS_SELECT == daemon->event_loop_syscall) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
+ _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
+ (int) client_socket,
+ (int) FD_SETSIZE);
+#endif
+ MHD_socket_close_chk_ (client_socket);
+#if EINVAL
+ errno = EINVAL;
+#endif
+ return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ }
+
+#ifdef MHD_socket_nosignal_
+ if (! MHD_socket_nosignal_ (client_socket))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED,
+ _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+#ifndef MSG_NOSIGNAL
+ /* Cannot use socket as it can produce SIGPIPE. */
+#ifdef ENOTSOCK
+ errno = ENOTSOCK;
+#endif /* ENOTSOCK */
+ return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED;
+#endif /* ! MSG_NOSIGNAL */
+ }
+#endif /* MHD_socket_nosignal_ */
+
+
+#ifdef HAVE_MESSAGES
+#if DEBUG_CONNECT
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_ACCEPTED,
+ _ ("Accepted connection on socket %d.\n"),
+ client_socket);
+#endif
+#endif
+ if ( (daemon->connections == daemon->global_connection_limit) ||
+ (MHD_NO == MHD_ip_limit_add (daemon,
+ addr,
+ addrlen)) )
+ {
+ /* above connection limit - reject */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LIMIT_CONNECTIONS_REACHED,
+ _ (
+ "Server reached connection limit. Closing inbound connection.\n"));
+#endif
+ MHD_socket_close_chk_ (client_socket);
+#if ENFILE
+ errno = ENFILE;
+#endif
+ return MHD_SC_LIMIT_CONNECTIONS_REACHED;
+ }
+
+ /* apply connection acceptance policy if present */
+ if ( (NULL != daemon->accept_policy_cb) &&
+ (MHD_NO ==
+ daemon->accept_policy_cb (daemon->accept_policy_cb_cls,
+ addr,
+ addrlen)) )
+ {
+#if DEBUG_CLOSE
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_POLICY_REJECTED,
+ _ ("Connection rejected by application. Closing connection.\n"));
+#endif
+#endif
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+#if EACCESS
+ errno = EACCESS;
+#endif
+ return MHD_SC_ACCEPT_POLICY_REJECTED;
+ }
+
+ if (NULL ==
+ (connection = MHD_calloc_ (1,
+ sizeof (struct MHD_Connection))))
+ {
+ eno = errno;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_MALLOC_FAILURE,
+ "Error allocating memory: %s\n",
+ MHD_strerror_ (errno));
+#endif
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ errno = eno;
+ return MHD_SC_CONNECTION_MALLOC_FAILURE;
+ }
+ connection->pool
+ = MHD_pool_create (daemon->connection_memory_limit_b);
+ if (NULL == connection->pool)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_POOL_MALLOC_FAILURE,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection);
+#if ENOMEM
+ errno = ENOMEM;
+#endif
+ return MHD_SC_POOL_MALLOC_FAILURE;
+ }
+
+ connection->connection_timeout = daemon->connection_default_timeout;
+ memcpy (&connection->addr,
+ addr,
+ addrlen);
+ connection->addr_len = addrlen;
+ connection->socket_fd = client_socket;
+ connection->sk_nonblck = non_blck;
+ connection->daemon = daemon;
+ connection->last_activity = MHD_monotonic_sec_counter ();
+
+#ifdef HTTPS_SUPPORT
+ if (NULL != daemon->tls_api)
+ {
+ connection->tls_cs
+ = daemon->tls_api->setup_connection (daemon->tls_api->cls,
+ NULL /* FIXME */);
+ if (NULL == connection->tls_cs)
+ {
+ eno = EINVAL;
+ sc = -1; // FIXME!
+ goto cleanup;
+ }
+ }
+ else
+#endif /* ! HTTPS_SUPPORT */
+ {
+ /* set default connection handlers */
+ connection->recv_cls = &recv_param_adapter;
+ connection->send_cls = &send_param_adapter;
+ }
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ /* Firm check under lock. */
+ if (daemon->connections >= daemon->global_connection_limit)
+ {
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ /* above connection limit - reject */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LIMIT_CONNECTIONS_REACHED,
+ _ (
+ "Server reached connection limit. Closing inbound connection.\n"));
+#endif
+#if ENFILE
+ eno = ENFILE;
+#endif
+ sc = MHD_SC_LIMIT_CONNECTIONS_REACHED;
+ goto cleanup;
+ }
+ daemon->connections++;
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ {
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ }
+ DLL_insert (daemon->connections_head,
+ daemon->connections_tail,
+ connection);
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+
+ if (NULL != daemon->notify_connection_cb)
+ daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
+ connection,
+ MHD_CONNECTION_NOTIFY_STARTED);
+
+ /* attempt to create handler thread */
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ {
+ if (! MHD_create_named_thread_ (&connection->pid,
+ "MHD-connection",
+ daemon->thread_stack_limit_b,
+ &thread_main_handle_connection,
+ connection))
+ {
+ eno = errno;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_THREAD_LAUNCH_FAILURE,
+ "Failed to create a thread: %s\n",
+ MHD_strerror_ (eno));
+#endif
+ sc = MHD_SC_THREAD_LAUNCH_FAILURE;
+ goto cleanup;
+ }
+ }
+ else
+ {
+ connection->pid = daemon->pid;
+ }
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if ( (! daemon->enable_turbo) ||
+ (external_add))
+ { /* Do not manipulate EReady DL-list in 'external_add' mode. */
+ struct epoll_event event;
+
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = connection;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ client_socket,
+ &event))
+ {
+ eno = errno;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ sc = MHD_SC_EPOLL_CTL_ADD_FAILED;
+ goto cleanup;
+ }
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ else
+ {
+ connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
+ | MHD_EPOLL_STATE_WRITE_READY
+ | MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ }
+ }
+ else /* This 'else' is combined with next 'if'. */
+#endif
+ if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
+ (external_add) &&
+ (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc,
+ "n")) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_USE_FAILED,
+ _ (
+ "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).\n"));
+#endif
+ }
+ return MHD_SC_OK;
+
+cleanup:
+ if (NULL != daemon->notify_connection_cb)
+ daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
+ connection,
+ MHD_CONNECTION_NOTIFY_CLOSED);
+#ifdef HTTPS_SUPPORT
+ if ( (NULL != daemon->tls_api) &&
+ (NULL != connection->tls_cs) )
+ daemon->tls_api->teardown_connection (daemon->tls_api->cls,
+ connection->tls_cs);
+#endif /* HTTPS_SUPPORT */
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ {
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ }
+ DLL_remove (daemon->connections_head,
+ daemon->connections_tail,
+ connection);
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ MHD_pool_destroy (connection->pool);
+ free (connection);
+ if (0 != eno)
+ errno = eno;
+ else
+ errno = EINVAL;
+ return sc;
+}
+
+
+/**
+ * Add another client connection to the set of connections managed by
+ * MHD. This API is usually not needed (since MHD will accept inbound
+ * connections on the server socket). Use this API in special cases,
+ * for example if your HTTP server is behind NAT and needs to connect
+ * out to the HTTP client, or if you are building a proxy.
+ *
+ * If you use this API in conjunction with a internal select or a
+ * thread pool, you must set the option #MHD_USE_ITC to ensure that
+ * the freshly added connection is immediately processed by MHD.
+ *
+ * The given client socket will be managed (and closed!) by MHD after
+ * this call and must no longer be used directly by the application
+ * afterwards.
+ *
+ * @param daemon daemon that manages the connection
+ * @param client_socket socket to manage (MHD will expect
+ * to receive an HTTP request from this socket next).
+ * @param addr IP address of the client
+ * @param addrlen number of bytes in @a addr
+ * @return #MHD_YES on success, #MHD_NO if this daemon could
+ * not handle the connection (i.e. malloc() failed, etc).
+ * The socket will be closed in any case; `errno` is
+ * set to indicate further details about the error.
+ * @ingroup specialized
+ */
+enum MHD_StatusCode
+MHD_daemon_add_connection (struct MHD_Daemon *daemon,
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ bool sk_nonbl;
+
+ if (! MHD_socket_nonblocking_ (client_socket))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
+ _ ("Failed to set nonblocking mode on new client socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ sk_nonbl = false;
+ }
+ else
+ {
+ sk_nonbl = true;
+ }
+
+ if ( (daemon->enable_turbo) &&
+ (! MHD_socket_noninheritable_ (client_socket)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
+ _ ("Failed to set noninheritable mode on new client socket.\n"));
+#endif
+ }
+ return internal_add_connection (daemon,
+ client_socket,
+ addr,
+ addrlen,
+ true,
+ sk_nonbl);
+}
+
+
+/**
+ * Accept an incoming connection and create the MHD_Connection object
+ * for it. This function also enforces policy by way of checking with
+ * the accept policy callback. @remark To be called only from thread
+ * that process daemon's select()/poll()/etc.
+ *
+ * @param daemon handle with the listen socket
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_accept_connection_ (struct MHD_Daemon *daemon)
+{
+ struct sockaddr_storage addrstorage;
+ struct sockaddr *addr = (struct sockaddr *) &addrstorage;
+ socklen_t addrlen;
+ MHD_socket s;
+ MHD_socket fd;
+ bool sk_nonbl;
+
+ addrlen = sizeof (addrstorage);
+ memset (addr,
+ 0,
+ sizeof (addrstorage));
+ if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_socket)) ||
+ (daemon->was_quiesced) )
+ return MHD_SC_DAEMON_ALREADY_QUIESCED;
+#ifdef USE_ACCEPT4
+ s = accept4 (fd,
+ addr,
+ &addrlen,
+ MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK);
+ sk_nonbl = (0 != MAYBE_SOCK_NONBLOCK);
+#else /* ! USE_ACCEPT4 */
+ s = accept (fd,
+ addr,
+ &addrlen);
+ sk_nonbl = false;
+#endif /* ! USE_ACCEPT4 */
+ if ( (MHD_INVALID_SOCKET == s) ||
+ (addrlen <= 0) )
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ /* This could be a common occurrence with multiple worker threads */
+ if (MHD_SCKT_ERR_IS_ (err,
+ MHD_SCKT_EINVAL_))
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */
+ if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err))
+ return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err) )
+ return MHD_SC_ACCEPT_FAILED_EAGAIN;
+ if (MHD_INVALID_SOCKET != s)
+ {
+ MHD_socket_close_chk_ (s);
+ }
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
+ {
+ /* system/process out of resources */
+ if (0 == daemon->connections)
+ {
+#ifdef HAVE_MESSAGES
+ /* Not setting 'at_limit' flag, as there is no way it
+ would ever be cleared. Instead trying to produce
+ bit fat ugly warning. */
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY,
+ _ (
+ "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
+#endif
+ return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY;
+ }
+ else
+ {
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ daemon->at_limit = true;
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED,
+ _ (
+ "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
+ (unsigned int) daemon->connections);
+#endif
+ return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED;
+ }
+ }
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY,
+ _ ("Error accepting connection: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY;
+ }
+#if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
+ if (! MHD_socket_nonblocking_ (s))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
+ _ (
+ "Failed to set nonblocking mode on incoming connection socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ }
+ else
+ sk_nonbl = true;
+#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
+#if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
+ if (! MHD_socket_noninheritable_ (s))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
+ _ (
+ "Failed to set noninheritable mode on incoming connection socket.\n"));
+#endif
+ }
+#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
+#ifdef HAVE_MESSAGES
+#if DEBUG_CONNECT
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_ACCEPTED,
+ _ ("Accepted connection on socket %d.\n"),
+ s);
+#endif
+#endif
+ return internal_add_connection (daemon,
+ s,
+ addr,
+ addrlen,
+ false,
+ sk_nonbl);
+}
+
+
+/* end of connection_add.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_add.h
^
|
@@ -0,0 +1,41 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_add.h
+ * @brief functions to add connection to our active set
+ * @author Christian Grothoff
+ */
+
+#ifndef CONNECTION_ADD_H
+#define CONNECTION_ADD_H
+
+/**
+ * Accept an incoming connection and create the MHD_Connection object
+ * for it. This function also enforces policy by way of checking with
+ * the accept policy callback. @remark To be called only from thread
+ * that process daemon's select()/poll()/etc.
+ *
+ * @param daemon handle with the listen socket
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_accept_connection_ (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_call_handlers.c
^
|
@@ -0,0 +1,3724 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_call_handlers.c
+ * @brief call the connection's handlers based on the event trigger
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_call_handlers.h"
+#include "connection_update_last_activity.h"
+#include "connection_close.h"
+
+
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#include <sys/sendfile.h>
+#endif /* MHD_LINUX_SOLARIS_SENDFILE */
+#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#endif /* HAVE_FREEBSD_SENDFILE || HAVE_DARWIN_SENDFILE */
+
+
+/**
+ * sendfile() chuck size
+ */
+#define MHD_SENFILE_CHUNK_ (0x20000)
+
+/**
+ * sendfile() chuck size for thread-per-connection
+ */
+#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
+
+
+/**
+ * Response text used when the request (http header) is too big to
+ * be processed.
+ *
+ * Intentionally empty here to keep our memory footprint
+ * minimal.
+ */
+#ifdef HAVE_MESSAGES
+#define REQUEST_TOO_BIG \
+ "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
+#else
+#define REQUEST_TOO_BIG ""
+#endif
+
+/**
+ * Response text used when the request (http header) does not
+ * contain a "Host:" header and still claims to be HTTP 1.1.
+ *
+ * Intentionally empty here to keep our memory footprint
+ * minimal.
+ */
+#ifdef HAVE_MESSAGES
+#define REQUEST_LACKS_HOST \
+ "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>"
+#else
+#define REQUEST_LACKS_HOST ""
+#endif
+
+/**
+ * Response text used when the request (http header) is
+ * malformed.
+ *
+ * Intentionally empty here to keep our memory footprint
+ * minimal.
+ */
+#ifdef HAVE_MESSAGES
+#define REQUEST_MALFORMED \
+ "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
+#else
+#define REQUEST_MALFORMED ""
+#endif
+
+/**
+ * Response text used when there is an internal server error.
+ *
+ * Intentionally empty here to keep our memory footprint
+ * minimal.
+ */
+#ifdef HAVE_MESSAGES
+#define INTERNAL_ERROR \
+ "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>"
+#else
+#define INTERNAL_ERROR ""
+#endif
+
+
+#ifdef HAVE_FREEBSD_SENDFILE
+#ifdef SF_FLAGS
+/**
+ * FreeBSD sendfile() flags
+ */
+static int freebsd_sendfile_flags_;
+
+/**
+ * FreeBSD sendfile() flags for thread-per-connection
+ */
+static int freebsd_sendfile_flags_thd_p_c_;
+#endif /* SF_FLAGS */
+
+
+/**
+ * Initialises static variables.
+ *
+ * FIXME: make sure its actually called!
+ */
+void
+MHD_conn_init_static_ (void)
+{
+/* FreeBSD 11 and later allow to specify read-ahead size
+ * and handles SF_NODISKIO differently.
+ * SF_FLAGS defined only on FreeBSD 11 and later. */
+#ifdef SF_FLAGS
+ long sys_page_size = sysconf (_SC_PAGESIZE);
+ if (0 > sys_page_size)
+ { /* Failed to get page size. */
+ freebsd_sendfile_flags_ = SF_NODISKIO;
+ freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
+ }
+ else
+ {
+ freebsd_sendfile_flags_ =
+ SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO);
+ freebsd_sendfile_flags_thd_p_c_ =
+ SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size),
+ SF_NODISKIO);
+ }
+#endif /* SF_FLAGS */
+}
+
+
+#endif /* HAVE_FREEBSD_SENDFILE */
+
+
+/**
+ * Message to transmit when http 1.1 request is received
+ */
+#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
+
+
+/**
+ * A serious error occurred, close the
+ * connection (and notify the application).
+ *
+ * @param connection connection to close with error
+ * @param sc the reason for closing the connection
+ * @param emsg error message (can be NULL)
+ */
+static void
+connection_close_error (struct MHD_Connection *connection,
+ enum MHD_StatusCode sc,
+ const char *emsg)
+{
+#ifdef HAVE_MESSAGES
+ if (NULL != emsg)
+ MHD_DLOG (connection->daemon,
+ sc,
+ emsg);
+#else /* ! HAVE_MESSAGES */
+ (void) emsg; /* Mute compiler warning. */
+ (void) sc;
+#endif /* ! HAVE_MESSAGES */
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+}
+
+
+/**
+ * Macro to only include error message in call to
+ * #connection_close_error() if we have HAVE_MESSAGES.
+ */
+#ifdef HAVE_MESSAGES
+#define CONNECTION_CLOSE_ERROR(c, sc, emsg) connection_close_error (c, sc, emsg)
+#else
+#define CONNECTION_CLOSE_ERROR(c, sc, emsg) connection_close_error (c, sc, NULL)
+#endif
+
+
+/**
+ * Try growing the read buffer. We initially claim half the available
+ * buffer space for the read buffer (the other half being left for
+ * management data structures; the write buffer can in the end take
+ * virtually everything as the read buffer can be reduced to the
+ * minimum necessary at that point.
+ *
+ * @param request the request for which to grow the buffer
+ * @return true on success, false on failure
+ */
+static bool
+try_grow_read_buffer (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ void *buf;
+ size_t new_size;
+
+ if (0 == request->read_buffer_size)
+ new_size = daemon->connection_memory_limit_b / 2;
+ else
+ new_size = request->read_buffer_size
+ + daemon->connection_memory_increment_b;
+ buf = MHD_pool_reallocate (request->connection->pool,
+ request->read_buffer,
+ request->read_buffer_size,
+ new_size);
+ if (NULL == buf)
+ return false;
+ /* we can actually grow the buffer, do it! */
+ request->read_buffer = buf;
+ request->read_buffer_size = new_size;
+ return true;
+}
+
+
+/**
+ * This function handles a particular request when it has been
+ * determined that there is data to be read off a socket.
+ *
+ * @param request request to handle
+ */
+static void
+MHD_request_handle_read_ (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ ssize_t bytes_read;
+
+ if ( (MHD_REQUEST_CLOSED == request->state) ||
+ (connection->suspended) )
+ return;
+#ifdef HTTPS_SUPPORT
+ {
+ struct MHD_TLS_Plugin *tls;
+
+ if ( (NULL != (tls = daemon->tls_api)) &&
+ (! tls->handshake (tls->cls,
+ connection->tls_cs)) )
+ return;
+ }
+#endif /* HTTPS_SUPPORT */
+
+ /* make sure "read" has a reasonable number of bytes
+ in buffer to use per system call (if possible) */
+ if (request->read_buffer_offset
+ + daemon->connection_memory_increment_b >
+ request->read_buffer_size)
+ try_grow_read_buffer (request);
+
+ if (request->read_buffer_size == request->read_buffer_offset)
+ return; /* No space for receiving data. */
+ bytes_read = connection->recv_cls (connection,
+ &request->read_buffer
+ [request->read_buffer_offset],
+ request->read_buffer_size
+ - request->read_buffer_offset);
+ if (bytes_read < 0)
+ {
+ if (MHD_ERR_AGAIN_ == bytes_read)
+ return; /* No new data to process. */
+ if (MHD_ERR_CONNRESET_ == bytes_read)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ (MHD_REQUEST_INIT == request->state)
+ ? MHD_SC_CONNECTION_CLOSED
+ : MHD_SC_CONNECTION_RESET_CLOSED,
+ (MHD_REQUEST_INIT == request->state)
+ ? NULL
+ : _ (
+ "Socket disconnected while reading request.\n"));
+ return;
+ }
+ CONNECTION_CLOSE_ERROR (connection,
+ (MHD_REQUEST_INIT == request->state)
+ ? MHD_SC_CONNECTION_CLOSED
+ : MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+ (MHD_REQUEST_INIT == request->state)
+ ? NULL
+ : _ (
+ "Connection socket is closed due to error when reading request.\n"));
+ return;
+ }
+
+ if (0 == bytes_read)
+ { /* Remote side closed connection. */
+ connection->read_closed = true;
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_CLIENT_ABORT);
+ return;
+ }
+ request->read_buffer_offset += bytes_read;
+ MHD_connection_update_last_activity_ (connection);
+#if DEBUG_STATES
+ MHD_DLOG (daemon,
+ MHD_SC_STATE_MACHINE_STATUS_REPORT,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (request->state));
+#endif
+ switch (request->state)
+ {
+ case MHD_REQUEST_INIT:
+ case MHD_REQUEST_URL_RECEIVED:
+ case MHD_REQUEST_HEADER_PART_RECEIVED:
+ case MHD_REQUEST_HEADERS_RECEIVED:
+ case MHD_REQUEST_HEADERS_PROCESSED:
+ case MHD_REQUEST_CONTINUE_SENDING:
+ case MHD_REQUEST_CONTINUE_SENT:
+ case MHD_REQUEST_BODY_RECEIVED:
+ case MHD_REQUEST_FOOTER_PART_RECEIVED:
+ /* nothing to do but default action */
+ if (connection->read_closed)
+ {
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_READ_ERROR);
+ }
+ return;
+ case MHD_REQUEST_CLOSED:
+ return;
+#ifdef UPGRADE_SUPPORT
+ case MHD_REQUEST_UPGRADE:
+ mhd_assert (0);
+ return;
+#endif /* UPGRADE_SUPPORT */
+ default:
+ /* shrink read buffer to how much is actually used */
+ MHD_pool_reallocate (connection->pool,
+ request->read_buffer,
+ request->read_buffer_size + 1,
+ request->read_buffer_offset);
+ break;
+ }
+ return;
+}
+
+
+#if defined(_MHD_HAVE_SENDFILE)
+/**
+ * Function for sending responses backed by file FD.
+ *
+ * @param connection the MHD connection structure
+ * @return actual number of bytes sent
+ */
+static ssize_t
+sendfile_adapter (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+ struct MHD_Request *request = &connection->request;
+ struct MHD_Response *response = request->response;
+ ssize_t ret;
+ const int file_fd = response->fd;
+ uint64_t left;
+ uint64_t offsetu64;
+#ifndef HAVE_SENDFILE64
+ const uint64_t max_off_t = (uint64_t) OFF_T_MAX;
+#else /* HAVE_SENDFILE64 */
+ const uint64_t max_off_t = (uint64_t) OFF64_T_MAX;
+#endif /* HAVE_SENDFILE64 */
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#ifndef HAVE_SENDFILE64
+ off_t offset;
+#else /* HAVE_SENDFILE64 */
+ off64_t offset;
+#endif /* HAVE_SENDFILE64 */
+#endif /* MHD_LINUX_SOLARIS_SENDFILE */
+#ifdef HAVE_FREEBSD_SENDFILE
+ off_t sent_bytes;
+ int flags = 0;
+#endif
+#ifdef HAVE_DARWIN_SENDFILE
+ off_t len;
+#endif /* HAVE_DARWIN_SENDFILE */
+ const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
+ daemon->threading_mode);
+ const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ :
+ MHD_SENFILE_CHUNK_;
+ size_t send_size = 0;
+
+ mhd_assert (MHD_resp_sender_sendfile == request->resp_sender);
+ offsetu64 = request->response_write_position + response->fd_off;
+ left = response->total_size - request->response_write_position;
+ /* Do not allow system to stick sending on single fast connection:
+ * use 128KiB chunks (2MiB for thread-per-connection). */
+ send_size = (left > chunk_size) ? chunk_size : (size_t) left;
+ if (max_off_t < offsetu64)
+ { /* Retry to send with standard 'send()'. */
+ request->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#ifndef HAVE_SENDFILE64
+ offset = (off_t) offsetu64;
+ ret = sendfile (connection->socket_fd,
+ file_fd,
+ &offset,
+ send_size);
+#else /* HAVE_SENDFILE64 */
+ offset = (off64_t) offsetu64;
+ ret = sendfile64 (connection->socket_fd,
+ file_fd,
+ &offset,
+ send_size);
+#endif /* HAVE_SENDFILE64 */
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* EAGAIN --- no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+#ifdef HAVE_LINUX_SENDFILE
+ if (MHD_SCKT_ERR_IS_ (err,
+ MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* sendfile() failed with EINVAL if mmap()-like operations are not
+ supported for FD or other 'unusual' errors occurred, so we should try
+ to fall back to 'SEND'; see also this thread for info on
+ odd libc/Linux behavior with sendfile:
+ http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */request->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+#else /* HAVE_SOLARIS_SENDFILE */
+ if ( (EAFNOSUPPORT == err) ||
+ (EINVAL == err) ||
+ (EOPNOTSUPP == err) )
+ { /* Retry with standard file reader. */
+ request->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ if ( (ENOTCONN == err) ||
+ (EPIPE == err) )
+ {
+ return MHD_ERR_CONNRESET_;
+ }
+ return MHD_ERR_BADF_; /* Fail hard */
+#endif /* HAVE_SOLARIS_SENDFILE */
+ }
+#ifdef EPOLL_SUPPORT
+ else if (send_size > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+#elif defined(HAVE_FREEBSD_SENDFILE)
+#ifdef SF_FLAGS
+ flags = used_thr_p_c ?
+ freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
+#endif /* SF_FLAGS */
+ if (0 != sendfile (file_fd,
+ connection->socket_fd,
+ (off_t) offsetu64,
+ send_size,
+ NULL,
+ &sent_bytes,
+ flags))
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
+ MHD_SCKT_ERR_IS_EINTR_ (err) ||
+ (EBUSY == err) )
+ {
+ mhd_assert (SSIZE_MAX >= sent_bytes);
+ if (0 != sent_bytes)
+ return (ssize_t) sent_bytes;
+
+ return MHD_ERR_AGAIN_;
+ }
+ /* Some unrecoverable error. Possibly file FD is not suitable
+ * for sendfile(). Retry with standard send(). */
+ request->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ mhd_assert (0 < sent_bytes);
+ mhd_assert (SSIZE_MAX >= sent_bytes);
+ ret = (ssize_t) sent_bytes;
+#elif defined(HAVE_DARWIN_SENDFILE)
+ len = (off_t) send_size; /* chunk always fit */
+ if (0 != sendfile (file_fd,
+ connection->socket_fd,
+ (off_t) offsetu64,
+ &len,
+ NULL,
+ 0))
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
+ MHD_SCKT_ERR_IS_EINTR_ (err))
+ {
+ mhd_assert (0 <= len);
+ mhd_assert (SSIZE_MAX >= len);
+ mhd_assert (send_size >= (size_t) len);
+ if (0 != len)
+ return (ssize_t) len;
+
+ return MHD_ERR_AGAIN_;
+ }
+ if ((ENOTCONN == err) ||
+ (EPIPE == err) )
+ return MHD_ERR_CONNRESET_;
+ if ((ENOTSUP == err) ||
+ (EOPNOTSUPP == err) )
+ { /* This file FD is not suitable for sendfile().
+ * Retry with standard send(). */
+ request->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ return MHD_ERR_BADF_; /* Return hard error. */
+ }
+ mhd_assert (0 <= len);
+ mhd_assert (SSIZE_MAX >= len);
+ mhd_assert (send_size >= (size_t) len);
+ ret = (ssize_t) len;
+#endif /* HAVE_FREEBSD_SENDFILE */
+ return ret;
+}
+
+
+#endif /* _MHD_HAVE_SENDFILE */
+
+
+/**
+ * Check if we are done sending the write-buffer. If so, transition
+ * into "next_state".
+ *
+ * @param connection connection to check write status for
+ * @param next_state the next state to transition to
+ * @return false if we are not done, true if we are
+ */
+static bool
+check_write_done (struct MHD_Request *request,
+ enum MHD_REQUEST_STATE next_state)
+{
+ if (request->write_buffer_append_offset !=
+ request->write_buffer_send_offset)
+ return false;
+ request->write_buffer_append_offset = 0;
+ request->write_buffer_send_offset = 0;
+ request->state = next_state;
+ MHD_pool_reallocate (request->connection->pool,
+ request->write_buffer,
+ request->write_buffer_size,
+ 0);
+ request->write_buffer = NULL;
+ request->write_buffer_size = 0;
+ return true;
+}
+
+
+/**
+ * Prepare the response buffer of this request for sending. Assumes
+ * that the response mutex is already held. If the transmission is
+ * complete, this function may close the socket (and return false).
+ *
+ * @param request the request handle
+ * @return false if readying the response failed (the
+ * lock on the response will have been released already
+ * in this case).
+ */
+static bool
+try_ready_normal_body (struct MHD_Request *request)
+{
+ struct MHD_Response *response = request->response;
+ struct MHD_Connection *connection = request->connection;
+ ssize_t ret;
+
+ if (NULL == response->crc)
+ return true;
+ if ( (0 == response->total_size) ||
+ (request->response_write_position == response->total_size) )
+ return true; /* 0-byte response is always ready */
+ if ( (response->data_start <=
+ request->response_write_position) &&
+ (response->data_size + response->data_start >
+ request->response_write_position) )
+ return true; /* response already ready */
+#if defined(_MHD_HAVE_SENDFILE)
+ if (MHD_resp_sender_sendfile == request->resp_sender)
+ {
+ /* will use sendfile, no need to bother response crc */
+ return true;
+ }
+#endif /* _MHD_HAVE_SENDFILE */
+
+ ret = response->crc (response->crc_cls,
+ request->response_write_position,
+ response->data,
+ (size_t) MHD_MIN ((uint64_t) response->data_buffer_size,
+ response->total_size
+ - request->response_write_position));
+ if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
+ (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) )
+ {
+ /* either error or http 1.0 transfer, close socket! */
+ response->total_size = request->response_write_position;
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ if ( ((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret)
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ else
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
+ _ (
+ "Closing connection (application reported error generating data).\n"));
+ return false;
+ }
+ response->data_start = request->response_write_position;
+ response->data_size = ret;
+ if (0 == ret)
+ {
+ request->state = MHD_REQUEST_NORMAL_BODY_UNREADY;
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ * Prepare the response buffer of this request for sending. Assumes
+ * that the response mutex is already held. If the transmission is
+ * complete, this function may close the socket (and return false).
+ *
+ * @param connection the connection
+ * @return false if readying the response failed
+ */
+static bool
+try_ready_chunked_body (struct MHD_Request *request)
+{
+ struct MHD_Connection *connection = request->connection;
+ struct MHD_Response *response = request->response;
+ struct MHD_Daemon *daemon = request->daemon;
+ ssize_t ret;
+ char *buf;
+ size_t size;
+ char cbuf[10]; /* 10: max strlen of "%x\r\n" */
+ int cblen;
+
+ if (NULL == response->crc)
+ return true;
+ if (0 == request->write_buffer_size)
+ {
+ size = MHD_MIN (daemon->connection_memory_limit_b,
+ 2 * (0xFFFFFF + sizeof(cbuf) + 2));
+ do
+ {
+ size /= 2;
+ if (size < 128)
+ {
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ /* not enough memory */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
+ _ ("Closing connection (out of memory).\n"));
+ return false;
+ }
+ buf = MHD_pool_allocate (connection->pool,
+ size,
+ MHD_NO);
+ }
+ while (NULL == buf);
+ request->write_buffer_size = size;
+ request->write_buffer = buf;
+ }
+
+ if (0 == response->total_size)
+ ret = 0; /* response must be empty, don't bother calling crc */
+ else if ( (response->data_start <=
+ request->response_write_position) &&
+ (response->data_start + response->data_size >
+ request->response_write_position) )
+ {
+ /* difference between response_write_position and data_start is less
+ than data_size which is size_t type, no need to check for overflow */
+ const size_t data_write_offset
+ = (size_t) (request->response_write_position - response->data_start);
+ /* buffer already ready, use what is there for the chunk */
+ ret = response->data_size - data_write_offset;
+ if ( ((size_t) ret) > request->write_buffer_size - sizeof (cbuf) - 2)
+ ret = request->write_buffer_size - sizeof (cbuf) - 2;
+ memcpy (&request->write_buffer[sizeof (cbuf)],
+ &response->data[data_write_offset],
+ ret);
+ }
+ else
+ {
+ /* buffer not in range, try to fill it */
+ ret = response->crc (response->crc_cls,
+ request->response_write_position,
+ &request->write_buffer[sizeof (cbuf)],
+ request->write_buffer_size - sizeof (cbuf) - 2);
+ }
+ if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret)
+ {
+ /* error, close socket! */
+ response->total_size = request->response_write_position;
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
+ _ (
+ "Closing connection (application error generating response).\n"));
+ return false;
+ }
+ if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
+ (0 == response->total_size) )
+ {
+ /* end of message, signal other side! */
+ memcpy (request->write_buffer,
+ "0\r\n",
+ 3);
+ request->write_buffer_append_offset = 3;
+ request->write_buffer_send_offset = 0;
+ response->total_size = request->response_write_position;
+ return true;
+ }
+ if (0 == ret)
+ {
+ request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY;
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ return false;
+ }
+ if (ret > 0xFFFFFF)
+ ret = 0xFFFFFF;
+ cblen = MHD_snprintf_ (cbuf,
+ sizeof (cbuf),
+ "%X\r\n",
+ (unsigned int) ret);
+ mhd_assert (cblen > 0);
+ mhd_assert ((size_t) cblen < sizeof(cbuf));
+ memcpy (&request->write_buffer[sizeof (cbuf) - cblen],
+ cbuf,
+ cblen);
+ memcpy (&request->write_buffer[sizeof (cbuf) + ret],
+ "\r\n",
+ 2);
+ request->response_write_position += ret;
+ request->write_buffer_send_offset = sizeof (cbuf) - cblen;
+ request->write_buffer_append_offset = sizeof (cbuf) + ret + 2;
+ return true;
+}
+
+
+/**
+ * This function was created to handle writes to sockets when it has
+ * been determined that the socket can be written to.
+ *
+ * @param request the request to handle
+ */
+static void
+MHD_request_handle_write_ (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ struct MHD_Response *response;
+ ssize_t ret;
+
+ if (connection->suspended)
+ return;
+#ifdef HTTPS_SUPPORT
+ {
+ struct MHD_TLS_Plugin *tls;
+
+ if ( (NULL != (tls = daemon->tls_api)) &&
+ (! tls->handshake (tls->cls,
+ connection->tls_cs)) )
+ return;
+ }
+#endif /* HTTPS_SUPPORT */
+
+#if DEBUG_STATES
+ MHD_DLOG (daemon,
+ MHD_SC_STATE_MACHINE_STATUS_REPORT,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (request->state));
+#endif
+ switch (request->state)
+ {
+ case MHD_REQUEST_INIT:
+ case MHD_REQUEST_URL_RECEIVED:
+ case MHD_REQUEST_HEADER_PART_RECEIVED:
+ case MHD_REQUEST_HEADERS_RECEIVED:
+ mhd_assert (0);
+ return;
+ case MHD_REQUEST_HEADERS_PROCESSED:
+ return;
+ case MHD_REQUEST_CONTINUE_SENDING:
+ ret = connection->send_cls (connection,
+ &HTTP_100_CONTINUE
+ [request->continue_message_write_offset],
+ MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)
+ - request->continue_message_write_offset);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ _ ("Failed to send data in request for %s.\n"),
+ request->url);
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ NULL);
+ return;
+ }
+ request->continue_message_write_offset += ret;
+ MHD_connection_update_last_activity_ (connection);
+ return;
+ case MHD_REQUEST_CONTINUE_SENT:
+ case MHD_REQUEST_BODY_RECEIVED:
+ case MHD_REQUEST_FOOTER_PART_RECEIVED:
+ case MHD_REQUEST_FOOTERS_RECEIVED:
+ mhd_assert (0);
+ return;
+ case MHD_REQUEST_HEADERS_SENDING:
+ ret = connection->send_cls (connection,
+ &request->write_buffer
+ [request->write_buffer_send_offset],
+ request->write_buffer_append_offset
+ - request->write_buffer_send_offset);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ _ (
+ "Connection was closed while sending response headers.\n"));
+ return;
+ }
+ request->write_buffer_send_offset += ret;
+ MHD_connection_update_last_activity_ (connection);
+ if (MHD_REQUEST_HEADERS_SENDING != request->state)
+ return;
+ check_write_done (request,
+ MHD_REQUEST_HEADERS_SENT);
+ return;
+ case MHD_REQUEST_HEADERS_SENT:
+ return;
+ case MHD_REQUEST_NORMAL_BODY_READY:
+ response = request->response;
+ if (request->response_write_position <
+ request->response->total_size)
+ {
+ uint64_t data_write_offset;
+
+ if (NULL != response->crc)
+ MHD_mutex_lock_chk_ (&response->mutex);
+ if (! try_ready_normal_body (request))
+ {
+ /* mutex was already unlocked by try_ready_normal_body */
+ return;
+ }
+#if defined(_MHD_HAVE_SENDFILE)
+ if (MHD_resp_sender_sendfile == request->resp_sender)
+ {
+ ret = sendfile_adapter (connection);
+ }
+ else
+#else /* ! _MHD_HAVE_SENDFILE */
+ if (1)
+#endif /* ! _MHD_HAVE_SENDFILE */
+ {
+ data_write_offset = request->response_write_position
+ - response->data_start;
+ if (data_write_offset > (uint64_t) SIZE_MAX)
+ MHD_PANIC (_ ("Data offset exceeds limit.\n"));
+ ret = connection->send_cls (connection,
+ &response->data
+ [(size_t) data_write_offset],
+ response->data_size
+ - (size_t) data_write_offset);
+#if DEBUG_SEND_DATA
+ if (ret > 0)
+ fprintf (stderr,
+ _ ("Sent %d-byte DATA response: `%.*s'\n"),
+ (int) ret,
+ (int) ret,
+ &response->data[request->response_write_position
+ - response->data_start]);
+#endif
+ }
+ if (NULL != response->crc)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ _ ("Failed to send data in request for `%s'.\n"),
+ request->url);
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ NULL);
+ return;
+ }
+ request->response_write_position += ret;
+ MHD_connection_update_last_activity_ (connection);
+ }
+ if (request->response_write_position ==
+ request->response->total_size)
+ request->state = MHD_REQUEST_FOOTERS_SENT; /* have no footers */
+ return;
+ case MHD_REQUEST_NORMAL_BODY_UNREADY:
+ mhd_assert (0);
+ return;
+ case MHD_REQUEST_CHUNKED_BODY_READY:
+ ret = connection->send_cls (connection,
+ &request->write_buffer
+ [request->write_buffer_send_offset],
+ request->write_buffer_append_offset
+ - request->write_buffer_send_offset);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ _ (
+ "Connection was closed while sending response body.\n"));
+ return;
+ }
+ request->write_buffer_send_offset += ret;
+ MHD_connection_update_last_activity_ (connection);
+ if (MHD_REQUEST_CHUNKED_BODY_READY != request->state)
+ return;
+ check_write_done (request,
+ (request->response->total_size ==
+ request->response_write_position) ?
+ MHD_REQUEST_BODY_SENT :
+ MHD_REQUEST_CHUNKED_BODY_UNREADY);
+ return;
+ case MHD_REQUEST_CHUNKED_BODY_UNREADY:
+ case MHD_REQUEST_BODY_SENT:
+ mhd_assert (0);
+ return;
+ case MHD_REQUEST_FOOTERS_SENDING:
+ ret = connection->send_cls (connection,
+ &request->write_buffer
+ [request->write_buffer_send_offset],
+ request->write_buffer_append_offset
+ - request->write_buffer_send_offset);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
+ _ (
+ "Connection was closed while sending response body.\n"));
+ return;
+ }
+ request->write_buffer_send_offset += ret;
+ MHD_connection_update_last_activity_ (connection);
+ if (MHD_REQUEST_FOOTERS_SENDING != request->state)
+ return;
+ check_write_done (request,
+ MHD_REQUEST_FOOTERS_SENT);
+ return;
+ case MHD_REQUEST_FOOTERS_SENT:
+ mhd_assert (0);
+ return;
+ case MHD_REQUEST_CLOSED:
+ return;
+#ifdef UPGRADE_SUPPORT
+ case MHD_REQUEST_UPGRADE:
+ mhd_assert (0);
+ return;
+#endif /* UPGRADE_SUPPORT */
+ default:
+ mhd_assert (0);
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED,
+ _ ("Internal error.\n"));
+ break;
+ }
+}
+
+
+/**
+ * Check whether request header contains particular token.
+ *
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Case-insensitive match used for header names and tokens.
+ * @param request the request to get values from
+ * @param header the header name
+ * @param token the token to find
+ * @param token_len the length of token, not including optional
+ * terminating null-character.
+ * @return true if token is found in specified header,
+ * false otherwise
+ */
+static bool
+MHD_lookup_header_token_ci (const struct MHD_Request *request,
+ const char *header,
+ const char *token,
+ size_t token_len)
+{
+ struct MHD_HTTP_Header *pos;
+
+ if ( (NULL == request) || /* FIXME: require non-null? */
+ (NULL == header) || /* FIXME: require non-null? */
+ (0 == header[0]) ||
+ (NULL == token) ||
+ (0 == token[0]) )
+ return false;
+ for (pos = request->headers_received; NULL != pos; pos = pos->next)
+ {
+ if ( (0 != (pos->kind & MHD_HEADER_KIND)) &&
+ ( (header == pos->header) ||
+ (MHD_str_equal_caseless_ (header,
+ pos->header)) ) &&
+ (MHD_str_has_token_caseless_ (pos->value,
+ token,
+ token_len)) )
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Check whether request header contains particular static @a tkn.
+ *
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Case-insensitive match used for header names and tokens.
+ * @param r the request to get values from
+ * @param h the header name
+ * @param tkn the static string of token to find
+ * @return true if token is found in specified header,
+ * false otherwise
+ */
+#define MHD_lookup_header_s_token_ci(r,h,tkn) \
+ MHD_lookup_header_token_ci ((r),(h),(tkn),MHD_STATICSTR_LEN_ (tkn))
+
+
+/**
+ * Are we allowed to keep the given connection alive? We can use the
+ * TCP stream for a second request if the connection is HTTP 1.1 and
+ * the "Connection" header either does not exist or is not set to
+ * "close", or if the connection is HTTP 1.0 and the "Connection"
+ * header is explicitly set to "keep-alive". If no HTTP version is
+ * specified (or if it is not 1.0 or 1.1), we definitively close the
+ * connection. If the "Connection" header is not exactly "close" or
+ * "keep-alive", we proceed to use the default for the respective HTTP
+ * version (which is conservative for HTTP 1.0, but might be a bit
+ * optimistic for HTTP 1.1).
+ *
+ * @param request the request to check for keepalive
+ * @return #MHD_YES if (based on the request), a keepalive is
+ * legal
+ */
+static bool
+keepalive_possible (struct MHD_Request *request)
+{
+ if (MHD_CONN_MUST_CLOSE == request->keepalive)
+ return false;
+ if (NULL == request->version_s)
+ return false;
+ if ( (NULL != request->response) &&
+ (request->response->v10_only) )
+ return false;
+
+ if (MHD_str_equal_caseless_ (request->version_s,
+ MHD_HTTP_VERSION_1_1))
+ {
+ if (MHD_lookup_header_s_token_ci (request,
+ MHD_HTTP_HEADER_CONNECTION,
+ "upgrade"))
+ return false;
+ if (MHD_lookup_header_s_token_ci (request,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close"))
+ return false;
+ return true;
+ }
+ if (MHD_str_equal_caseless_ (request->version_s,
+ MHD_HTTP_VERSION_1_0))
+ {
+ if (MHD_lookup_header_s_token_ci (request,
+ MHD_HTTP_HEADER_CONNECTION,
+ "Keep-Alive"))
+ return true;
+ return false;
+ }
+ return false;
+}
+
+
+/**
+ * Produce HTTP time stamp.
+ *
+ * @param date where to write the header, with
+ * at least 128 bytes available space.
+ * @param date_len number of bytes in @a date
+ */
+static void
+get_date_string (char *date,
+ size_t date_len)
+{
+ static const char *const days[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char *const mons[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ struct tm now;
+ time_t t;
+#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
+ ! defined(HAVE_GMTIME_R)
+ struct tm*pNow;
+#endif
+
+ date[0] = 0;
+ time (&t);
+#if defined(HAVE_C11_GMTIME_S)
+ if (NULL == gmtime_s (&t,
+ &now))
+ return;
+#elif defined(HAVE_W32_GMTIME_S)
+ if (0 != gmtime_s (&now,
+ &t))
+ return;
+#elif defined(HAVE_GMTIME_R)
+ if (NULL == gmtime_r (&t,
+ &now))
+ return;
+#else
+ pNow = gmtime (&t);
+ if (NULL == pNow)
+ return;
+ now = *pNow;
+#endif
+ MHD_snprintf_ (date,
+ date_len,
+ "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
+ days[now.tm_wday % 7],
+ (unsigned int) now.tm_mday,
+ mons[now.tm_mon % 12],
+ (unsigned int) (1900 + now.tm_year),
+ (unsigned int) now.tm_hour,
+ (unsigned int) now.tm_min,
+ (unsigned int) now.tm_sec);
+}
+
+
+/**
+ * Check whether response header contains particular @a token.
+ *
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Case-insensitive match used for header names and tokens.
+ * @param response the response to query
+ * @param key header name
+ * @param token the token to find
+ * @param token_len the length of token, not including optional
+ * terminating null-character.
+ * @return true if token is found in specified header,
+ * false otherwise
+ */
+static bool
+check_response_header_token_ci (const struct MHD_Response *response,
+ const char *key,
+ const char *token,
+ size_t token_len)
+{
+ struct MHD_HTTP_Header *pos;
+
+ if ( (NULL == key) ||
+ ('\0' == key[0]) ||
+ (NULL == token) ||
+ ('\0' == token[0]) )
+ return false;
+
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if ( (pos->kind == MHD_HEADER_KIND) &&
+ MHD_str_equal_caseless_ (pos->header,
+ key) &&
+ MHD_str_has_token_caseless_ (pos->value,
+ token,
+ token_len) )
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Check whether response header contains particular static @a tkn.
+ *
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Case-insensitive match used for header names and tokens.
+ * @param r the response to query
+ * @param k header name
+ * @param tkn the static string of token to find
+ * @return true if token is found in specified header,
+ * false otherwise
+ */
+#define check_response_header_s_token_ci(r,k,tkn) \
+ check_response_header_token_ci ((r),(k),(tkn),MHD_STATICSTR_LEN_ (tkn))
+
+
+/**
+ * Allocate the connection's write buffer and fill it with all of the
+ * headers (or footers, if we have already sent the body) from the
+ * HTTPd's response. If headers are missing in the response supplied
+ * by the application, additional headers may be added here.
+ *
+ * @param request the request for which to build the response header
+ * @return true on success, false on failure (out of memory)
+ */
+static bool
+build_header_response (struct MHD_Request *request)
+{
+ struct MHD_Connection *connection = request->connection;
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Response *response = request->response;
+ size_t size;
+ size_t off;
+ struct MHD_HTTP_Header *pos;
+ char code[256];
+ char date[128];
+ size_t datelen;
+ char content_length_buf[128];
+ size_t content_length_len;
+ char *data;
+ enum MHD_ValueKind kind;
+ bool client_requested_close;
+ bool response_has_close;
+ bool response_has_keepalive;
+ const char *have_encoding;
+ const char *have_content_length;
+ bool must_add_close;
+ bool must_add_chunked_encoding;
+ bool must_add_keep_alive;
+ bool must_add_content_length;
+
+ mhd_assert (NULL != request->version_s);
+ if (0 == request->version_s[0])
+ {
+ data = MHD_pool_allocate (connection->pool,
+ 0,
+ MHD_YES);
+ request->write_buffer = data;
+ request->write_buffer_append_offset = 0;
+ request->write_buffer_send_offset = 0;
+ request->write_buffer_size = 0;
+ return true;
+ }
+ if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
+ {
+ const char *reason_phrase;
+ const char *version;
+
+ reason_phrase
+ = MHD_get_reason_phrase_for (response->status_code);
+ version
+ = (response->icy)
+ ? "ICY"
+ : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
+ request->version_s))
+ ? MHD_HTTP_VERSION_1_0
+ : MHD_HTTP_VERSION_1_1);
+ MHD_snprintf_ (code,
+ sizeof (code),
+ "%s %u %s\r\n",
+ version,
+ response->status_code,
+ reason_phrase);
+ off = strlen (code);
+ /* estimate size */
+ size = off + 2; /* +2 for extra "\r\n" at the end */
+ kind = MHD_HEADER_KIND;
+ if ( (! daemon->suppress_date) &&
+ (NULL == MHD_response_get_header (response,
+ MHD_HTTP_HEADER_DATE)) )
+ get_date_string (date,
+ sizeof (date));
+ else
+ date[0] = '\0';
+ datelen = strlen (date);
+ size += datelen;
+ }
+ else
+ {
+ /* 2 bytes for final CRLF of a Chunked-Body */
+ size = 2;
+ kind = MHD_FOOTER_KIND;
+ off = 0;
+ datelen = 0;
+ }
+
+ /* calculate extra headers we need to add, such as 'Connection: close',
+ first see what was explicitly requested by the application */
+ must_add_close = false;
+ must_add_chunked_encoding = false;
+ must_add_keep_alive = false;
+ must_add_content_length = false;
+ response_has_close = false;
+ switch (request->state)
+ {
+ case MHD_REQUEST_FOOTERS_RECEIVED:
+ response_has_close
+ = check_response_header_s_token_ci (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
+ response_has_keepalive
+ = check_response_header_s_token_ci (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "Keep-Alive");
+ client_requested_close
+ = MHD_lookup_header_s_token_ci (request,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
+
+ if (response->v10_only)
+ request->keepalive = MHD_CONN_MUST_CLOSE;
+#ifdef UPGRADE_SUPPORT
+ else if (NULL != response->upgrade_handler)
+ /* If this connection will not be "upgraded", it must be closed. */
+ request->keepalive = MHD_CONN_MUST_CLOSE;
+#endif /* UPGRADE_SUPPORT */
+
+ /* now analyze chunked encoding situation */
+ request->have_chunked_upload = false;
+
+ if ( (MHD_SIZE_UNKNOWN == response->total_size) &&
+#ifdef UPGRADE_SUPPORT
+ (NULL == response->upgrade_handler) &&
+#endif /* UPGRADE_SUPPORT */
+ (! response_has_close) &&
+ (! client_requested_close) )
+ {
+ /* size is unknown, and close was not explicitly requested;
+ need to either to HTTP 1.1 chunked encoding or
+ close the connection */
+ /* 'close' header doesn't exist yet, see if we need to add one;
+ if the client asked for a close, no need to start chunk'ing */
+ if ( (keepalive_possible (request)) &&
+ (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
+ request->version_s)) )
+ {
+ have_encoding
+ = MHD_response_get_header (response,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING);
+ if (NULL == have_encoding)
+ {
+ must_add_chunked_encoding = true;
+ request->have_chunked_upload = true;
+ }
+ else if (MHD_str_equal_caseless_ (have_encoding,
+ "identity"))
+ {
+ /* application forced identity encoding, can't do 'chunked' */
+ must_add_close = true;
+ }
+ else
+ {
+ request->have_chunked_upload = true;
+ }
+ }
+ else
+ {
+ /* Keep alive or chunking not possible
+ => set close header if not present */
+ if (! response_has_close)
+ must_add_close = true;
+ }
+ }
+
+ /* check for other reasons to add 'close' header */
+ if ( ( (client_requested_close) ||
+ (connection->read_closed) ||
+ (MHD_CONN_MUST_CLOSE == request->keepalive)) &&
+ (! response_has_close) &&
+#ifdef UPGRADE_SUPPORT
+ (NULL == response->upgrade_handler) &&
+#endif /* UPGRADE_SUPPORT */
+ (! response->v10_only) )
+ must_add_close = true;
+
+ /* check if we should add a 'content length' header */
+ have_content_length
+ = MHD_response_get_header (response,
+ MHD_HTTP_HEADER_CONTENT_LENGTH);
+
+ /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status
+ codes SHOULD NOT have a Content-Length according to spec;
+ also chunked encoding / unknown length or CONNECT... */
+ if ( (MHD_SIZE_UNKNOWN != response->total_size) &&
+ (MHD_HTTP_NO_CONTENT != response->status_code) &&
+ (MHD_HTTP_NOT_MODIFIED != response->status_code) &&
+ (MHD_HTTP_OK <= response->status_code) &&
+ (NULL == have_content_length) &&
+ (request->method != MHD_METHOD_CONNECT) )
+ {
+ /*
+ Here we add a content-length if one is missing; however,
+ for 'connect' methods, the responses MUST NOT include a
+ content-length header *if* the response code is 2xx (in
+ which case we expect there to be no body). Still,
+ as we don't know the response code here in some cases, we
+ simply only force adding a content-length header if this
+ is not a 'connect' or if the response is not empty
+ (which is kind of more sane, because if some crazy
+ application did return content with a 2xx status code,
+ then having a content-length might again be a good idea).
+
+ Note that the change from 'SHOULD NOT' to 'MUST NOT' is
+ a recent development of the HTTP 1.1 specification.
+ */content_length_len
+ = MHD_snprintf_ (content_length_buf,
+ sizeof (content_length_buf),
+ MHD_HTTP_HEADER_CONTENT_LENGTH ": "
+ MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
+ (MHD_UNSIGNED_LONG_LONG) response->total_size);
+ must_add_content_length = true;
+ }
+
+ /* check for adding keep alive */
+ if ( (! response_has_keepalive) &&
+ (! response_has_close) &&
+ (! must_add_close) &&
+ (MHD_CONN_MUST_CLOSE != request->keepalive) &&
+#ifdef UPGRADE_SUPPORT
+ (NULL == response->upgrade_handler) &&
+#endif /* UPGRADE_SUPPORT */
+ (keepalive_possible (request)) )
+ must_add_keep_alive = true;
+ break;
+ case MHD_REQUEST_BODY_SENT:
+ response_has_keepalive = false;
+ break;
+ default:
+ mhd_assert (0);
+ return MHD_NO;
+ }
+
+ if (MHD_CONN_MUST_CLOSE != request->keepalive)
+ {
+ if ( (must_add_close) ||
+ (response_has_close) )
+ request->keepalive = MHD_CONN_MUST_CLOSE;
+ else if ( (must_add_keep_alive) ||
+ (response_has_keepalive) )
+ request->keepalive = MHD_CONN_USE_KEEPALIVE;
+ }
+
+ if (must_add_close)
+ size += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
+ if (must_add_keep_alive)
+ size += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n");
+ if (must_add_chunked_encoding)
+ size += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
+ if (must_add_content_length)
+ size += content_length_len;
+ mhd_assert (! (must_add_close && must_add_keep_alive) );
+ mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
+
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
+ {
+ /* TODO: add proper support for excluding "Keep-Alive" token. */
+ if ( (pos->kind == kind) &&
+ (! ( (must_add_close) &&
+ (response_has_keepalive) &&
+ (MHD_str_equal_caseless_ (pos->header,
+ MHD_HTTP_HEADER_CONNECTION)) &&
+ (MHD_str_equal_caseless_ (pos->value,
+ "Keep-Alive")) ) ) )
+ size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */
+ }
+ /* produce data */
+ data = MHD_pool_allocate (connection->pool,
+ size + 1,
+ MHD_NO);
+ if (NULL == data)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
+ "Not enough memory for write!\n");
+#endif
+ return false;
+ }
+ if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
+ {
+ memcpy (data,
+ code,
+ off);
+ }
+ if (must_add_close)
+ {
+ /* we must add the 'Connection: close' header */
+ memcpy (&data[off],
+ "Connection: close\r\n",
+ MHD_STATICSTR_LEN_ ("Connection: close\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
+ }
+ if (must_add_keep_alive)
+ {
+ /* we must add the 'Connection: Keep-Alive' header */
+ memcpy (&data[off],
+ "Connection: Keep-Alive\r\n",
+ MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n");
+ }
+ if (must_add_chunked_encoding)
+ {
+ /* we must add the 'Transfer-Encoding: chunked' header */
+ memcpy (&data[off],
+ "Transfer-Encoding: chunked\r\n",
+ MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
+ }
+ if (must_add_content_length)
+ {
+ /* we must add the 'Content-Length' header */
+ memcpy (&data[off],
+ content_length_buf,
+ content_length_len);
+ off += content_length_len;
+ }
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
+ {
+ /* TODO: add proper support for excluding "Keep-Alive" token. */
+ if ( (pos->kind == kind) &&
+ (! ( (must_add_close) &&
+ (response_has_keepalive) &&
+ (MHD_str_equal_caseless_ (pos->header,
+ MHD_HTTP_HEADER_CONNECTION)) &&
+ (MHD_str_equal_caseless_ (pos->value,
+ "Keep-Alive")) ) ) )
+ off += MHD_snprintf_ (&data[off],
+ size - off,
+ "%s: %s\r\n",
+ pos->header,
+ pos->value);
+ }
+ if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
+ {
+ memcpy (&data[off],
+ date,
+ datelen);
+ off += datelen;
+ }
+ memcpy (&data[off],
+ "\r\n",
+ 2);
+ off += 2;
+
+ if (off != size)
+ mhd_panic (mhd_panic_cls,
+ __FILE__,
+ __LINE__,
+ NULL);
+ request->write_buffer = data;
+ request->write_buffer_append_offset = size;
+ request->write_buffer_send_offset = 0;
+ request->write_buffer_size = size + 1;
+ return true;
+}
+
+
+/**
+ * We encountered an error processing the request. Handle it properly
+ * by stopping to read data and sending the indicated response code
+ * and message.
+ *
+ * @param request the request
+ * @param ec error code for MHD
+ * @param status_code the response code to send (400, 413 or 414)
+ * @param message the error message to send
+ */
+static void
+transmit_error_response (struct MHD_Request *request,
+ enum MHD_StatusCode ec,
+ enum MHD_HTTP_StatusCode status_code,
+ const char *message)
+{
+ struct MHD_Response *response;
+
+ if (NULL == request->version_s)
+ {
+ /* we were unable to process the full header line, so we don't
+ really know what version the client speaks; assume 1.0 */
+ request->version_s = MHD_HTTP_VERSION_1_0;
+ }
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ request->connection->read_closed = true;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (request->daemon,
+ ec,
+ _ (
+ "Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
+ status_code,
+ message);
+#endif
+ if (NULL != request->response)
+ {
+ MHD_response_queue_for_destroy (request->response);
+ request->response = NULL;
+ }
+ response = MHD_response_from_buffer (status_code,
+ strlen (message),
+ (void *) message,
+ MHD_RESPMEM_PERSISTENT);
+ request->response = response;
+ /* Do not reuse this connection. */
+ request->keepalive = MHD_CONN_MUST_CLOSE;
+ if (! build_header_response (request))
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (request->connection,
+ ec,
+ _ (
+ "Closing connection (failed to create response header).\n"));
+ }
+ else
+ {
+ request->state = MHD_REQUEST_HEADERS_SENDING;
+ }
+}
+
+
+/**
+ * Convert @a method to the respective enum value.
+ *
+ * @param method the method string to look up enum value for
+ * @return resulting enum, or generic value for "unknown"
+ */
+static enum MHD_Method
+method_string_to_enum (const char *method)
+{
+ static const struct
+ {
+ const char *key;
+ enum MHD_Method value;
+ } methods[] = {
+ { "OPTIONS", MHD_METHOD_OPTIONS },
+ { "GET", MHD_METHOD_GET },
+ { "HEAD", MHD_METHOD_HEAD },
+ { "POST", MHD_METHOD_POST },
+ { "PUT", MHD_METHOD_PUT },
+ { "DELETE", MHD_METHOD_DELETE },
+ { "TRACE", MHD_METHOD_TRACE },
+ { "CONNECT", MHD_METHOD_CONNECT },
+ { "ACL", MHD_METHOD_ACL },
+ { "BASELINE_CONTROL", MHD_METHOD_BASELINE_CONTROL },
+ { "BIND", MHD_METHOD_BIND },
+ { "CHECKIN", MHD_METHOD_CHECKIN },
+ { "CHECKOUT", MHD_METHOD_CHECKOUT },
+ { "COPY", MHD_METHOD_COPY },
+ { "LABEL", MHD_METHOD_LABEL },
+ { "LINK", MHD_METHOD_LINK },
+ { "LOCK", MHD_METHOD_LOCK },
+ { "MERGE", MHD_METHOD_MERGE },
+ { "MKACTIVITY", MHD_METHOD_MKACTIVITY },
+ { "MKCOL", MHD_METHOD_MKCOL },
+ { "MKREDIRECTREF", MHD_METHOD_MKREDIRECTREF },
+ { "MKWORKSPACE", MHD_METHOD_MKWORKSPACE },
+ { "MOVE", MHD_METHOD_MOVE },
+ { "ORDERPATCH", MHD_METHOD_ORDERPATCH },
+ { "PRI", MHD_METHOD_PRI },
+ { "PROPFIND", MHD_METHOD_PROPFIND },
+ { "PROPPATCH", MHD_METHOD_PROPPATCH },
+ { "REBIND", MHD_METHOD_REBIND },
+ { "REPORT", MHD_METHOD_REPORT },
+ { "SEARCH", MHD_METHOD_SEARCH },
+ { "UNBIND", MHD_METHOD_UNBIND },
+ { "UNCHECKOUT", MHD_METHOD_UNCHECKOUT },
+ { "UNLINK", MHD_METHOD_UNLINK },
+ { "UNLOCK", MHD_METHOD_UNLOCK },
+ { "UPDATE", MHD_METHOD_UPDATE },
+ { "UPDATEDIRECTREF", MHD_METHOD_UPDATEDIRECTREF },
+ { "VERSION-CONTROL", MHD_METHOD_VERSION_CONTROL },
+ { NULL, MHD_METHOD_UNKNOWN } /* must be last! */
+ };
+ unsigned int i;
+
+ for (i = 0; NULL != methods[i].key; i++)
+ if (0 ==
+ MHD_str_equal_caseless_ (method,
+ methods[i].key))
+ return methods[i].value;
+ return MHD_METHOD_UNKNOWN;
+}
+
+
+/**
+ * Add an entry to the HTTP headers of a request. If this fails,
+ * transmit an error response (request too big).
+ *
+ * @param request the request for which a value should be set
+ * @param kind kind of the value
+ * @param key key for the value
+ * @param value the value itself
+ * @return false on failure (out of memory), true for success
+ */
+static bool
+request_add_header (struct MHD_Request *request,
+ const char *key,
+ const char *value,
+ enum MHD_ValueKind kind)
+{
+ if (MHD_NO ==
+ MHD_request_set_value (request,
+ kind,
+ key,
+ value))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (request->daemon,
+ MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
+ _ ("Not enough memory in pool to allocate header record!\n"));
+#endif
+ transmit_error_response (request,
+ MHD_SC_CLIENT_HEADER_TOO_BIG,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ * Parse the first line of the HTTP HEADER.
+ *
+ * @param connection the connection (updated)
+ * @param line the first line, not 0-terminated
+ * @param line_len length of the first @a line
+ * @return true if the line is ok, false if it is malformed
+ */
+static bool
+parse_initial_message_line (struct MHD_Request *request,
+ char *line,
+ size_t line_len)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ const char *curi;
+ char *uri;
+ char *http_version;
+ char *args;
+ unsigned int unused_num_headers;
+ size_t url_end;
+
+ if (NULL == (uri = memchr (line,
+ ' ',
+ line_len)))
+ return false; /* serious error */
+ uri[0] = '\0';
+ request->method_s = line;
+ request->method = method_string_to_enum (line);
+ uri++;
+ /* Skip any spaces. Not required by standard but allow
+ to be more tolerant. */
+ while ( (' ' == uri[0]) &&
+ ( (size_t) (uri - line) < line_len) )
+ uri++;
+ if ((size_t) (uri - line) == line_len)
+ {
+ curi = "";
+ uri = NULL;
+ request->version_s = "";
+ args = NULL;
+ url_end = line_len - (line - uri); // EH, this is garbage. FIXME!
+ }
+ else
+ {
+ curi = uri;
+ /* Search from back to accept malformed URI with space */
+ http_version = line + line_len - 1;
+ /* Skip any trailing spaces */
+ while ( (' ' == http_version[0]) &&
+ (http_version > uri) )
+ http_version--;
+ /* Find first space in reverse direction */
+ while ( (' ' != http_version[0]) &&
+ (http_version > uri) )
+ http_version--;
+ if (http_version > uri)
+ {
+ http_version[0] = '\0';
+ request->version_s = http_version + 1;
+ args = memchr (uri,
+ '?',
+ http_version - uri);
+ }
+ else
+ {
+ request->version_s = "";
+ args = memchr (uri,
+ '?',
+ line_len - (uri - line));
+ }
+ url_end = http_version - uri;
+ }
+ if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) &&
+ (NULL != memchr (curi,
+ ' ',
+ url_end)) )
+ {
+ /* space exists in URI and we are supposed to be strict, reject */
+ return MHD_NO;
+ }
+ if (NULL != daemon->early_uri_logger_cb)
+ {
+ request->client_context
+ = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls,
+ curi,
+ request);
+ }
+ if (NULL != args)
+ {
+ args[0] = '\0';
+ args++;
+ /* note that this call clobbers 'args' */
+ MHD_parse_arguments_ (request,
+ MHD_GET_ARGUMENT_KIND,
+ args,
+ &request_add_header,
+ &unused_num_headers);
+ }
+ if (NULL != uri)
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ uri);
+ request->url = curi;
+ return true;
+}
+
+
+/**
+ * We have received (possibly the beginning of) a line in the
+ * header (or footer). Validate (check for ":") and prepare
+ * to process.
+ *
+ * @param request the request we're processing
+ * @param line line from the header to process
+ * @return true on success, false on error (malformed @a line)
+ */
+static bool
+process_header_line (struct MHD_Request *request,
+ char *line)
+{
+ struct MHD_Connection *connection = request->connection;
+ char *colon;
+
+ /* line should be normal header line, find colon */
+ colon = strchr (line,
+ ':');
+ if (NULL == colon)
+ {
+ /* error in header line, die hard */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ _ (
+ "Received malformed line (no colon). Closing connection.\n"));
+ return false;
+ }
+ if (MHD_PSL_PERMISSIVE != request->daemon->protocol_strict_level)
+ {
+ /* check for whitespace before colon, which is not allowed
+ by RFC 7230 section 3.2.4; we count space ' ' and
+ tab '\t', but not '\r\n' as those would have ended the line. */
+ const char *white;
+
+ white = strchr (line,
+ (unsigned char) ' ');
+ if ( (NULL != white) &&
+ (white < colon) )
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ _ (
+ "Whitespace before colon forbidden by RFC 7230. Closing connection.\n"));
+ return false;
+ }
+ white = strchr (line,
+ (unsigned char) '\t');
+ if ( (NULL != white) &&
+ (white < colon) )
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ _ (
+ "Tab before colon forbidden by RFC 7230. Closing connection.\n"));
+ return false;
+ }
+ }
+ /* zero-terminate header */
+ colon[0] = '\0';
+ colon++; /* advance to value */
+ while ( ('\0' != colon[0]) &&
+ ( (' ' == colon[0]) ||
+ ('\t' == colon[0]) ) )
+ colon++;
+ /* we do the actual adding of the connection
+ header at the beginning of the while
+ loop since we need to be able to inspect
+ the *next* header line (in case it starts
+ with a space...) */request->last = line;
+ request->colon = colon;
+ return true;
+}
+
+
+/**
+ * Process a header value that spans multiple lines.
+ * The previous line(s) are in connection->last.
+ *
+ * @param request the request we're processing
+ * @param line the current input line
+ * @param kind if the line is complete, add a header
+ * of the given kind
+ * @return true if the line was processed successfully
+ */
+static bool
+process_broken_line (struct MHD_Request *request,
+ char *line,
+ enum MHD_ValueKind kind)
+{
+ struct MHD_Connection *connection = request->connection;
+ char *last;
+ char *tmp;
+ size_t last_len;
+ size_t tmp_len;
+
+ last = request->last;
+ if ( (' ' == line[0]) ||
+ ('\t' == line[0]) )
+ {
+ /* value was continued on the next line, see
+ http://www.jmarshall.com/easy/http/ */
+ last_len = strlen (last);
+ /* skip whitespace at start of 2nd line */
+ tmp = line;
+ while ( (' ' == tmp[0]) ||
+ ('\t' == tmp[0]) )
+ tmp++;
+ tmp_len = strlen (tmp);
+ /* FIXME: we might be able to do this better (faster!), as most
+ likely 'last' and 'line' should already be adjacent in
+ memory; however, doing this right gets tricky if we have a
+ value continued over multiple lines (in which case we need to
+ record how often we have done this so we can check for
+ adjacency); also, in the case where these are not adjacent
+ (not sure how it can happen!), we would want to allocate from
+ the end of the pool, so as to not destroy the read-buffer's
+ ability to grow nicely. */last = MHD_pool_reallocate (connection->pool,
+ last,
+ last_len + 1,
+ last_len + tmp_len + 1);
+ if (NULL == last)
+ {
+ transmit_error_response (request,
+ MHD_SC_CLIENT_HEADER_TOO_BIG,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return MHD_NO;
+ }
+ memcpy (&last[last_len],
+ tmp,
+ tmp_len + 1);
+ request->last = last;
+ return MHD_YES; /* possibly more than 2 lines... */
+ }
+ mhd_assert ( (NULL != last) &&
+ (NULL != request->colon) );
+ if (! request_add_header (request,
+ last,
+ request->colon,
+ kind))
+ {
+ transmit_error_response (request,
+ MHD_SC_CLIENT_HEADER_TOO_BIG,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return false;
+ }
+ /* we still have the current line to deal with... */
+ if ('\0' != line[0])
+ {
+ if (! process_header_line (request,
+ line))
+ {
+ transmit_error_response (request,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/**
+ * Parse a single line of the HTTP header. Advance read_buffer (!)
+ * appropriately. If the current line does not fit, consider growing
+ * the buffer. If the line is far too long, close the connection. If
+ * no line is found (incomplete, buffer too small, line too long),
+ * return NULL. Otherwise return a pointer to the line.
+ *
+ * @param request request we're processing
+ * @param[out] line_len pointer to variable that receive
+ * length of line or NULL
+ * @return NULL if no full line is available; note that the returned
+ * string will not be 0-termianted
+ */
+static char *
+get_next_header_line (struct MHD_Request *request,
+ size_t *line_len)
+{
+ char *rbuf;
+ size_t pos;
+
+ if (0 == request->read_buffer_offset)
+ return NULL;
+ pos = 0;
+ rbuf = request->read_buffer;
+ while ( (pos < request->read_buffer_offset - 1) &&
+ ('\r' != rbuf[pos]) &&
+ ('\n' != rbuf[pos]) )
+ pos++;
+ if ( (pos == request->read_buffer_offset - 1) &&
+ ('\n' != rbuf[pos]) )
+ {
+ /* not found, consider growing... */
+ if ( (request->read_buffer_offset == request->read_buffer_size) &&
+ (! try_grow_read_buffer (request)) )
+ {
+ transmit_error_response (request,
+ MHD_SC_CLIENT_HEADER_TOO_BIG,
+ (NULL != request->url)
+ ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
+ : MHD_HTTP_URI_TOO_LONG,
+ REQUEST_TOO_BIG);
+ }
+ if (line_len)
+ *line_len = 0;
+ return NULL;
+ }
+
+ if (line_len)
+ *line_len = pos;
+ /* found, check if we have proper LFCR */
+ if ( ('\r' == rbuf[pos]) &&
+ ('\n' == rbuf[pos + 1]) )
+ rbuf[pos++] = '\0'; /* skip both r and n */
+ rbuf[pos++] = '\0';
+ request->read_buffer += pos;
+ request->read_buffer_size -= pos;
+ request->read_buffer_offset -= pos;
+ return rbuf;
+}
+
+
+/**
+ * Check whether is possible to force push socket buffer content as
+ * partial packet.
+ * MHD use different buffering logic depending on whether flushing of
+ * socket buffer is possible or not.
+ * If flushing IS possible than MHD activates extra buffering before
+ * sending data to prevent sending partial packets and flush pending
+ * data in socket buffer to push last partial packet to client after
+ * sending logical completed part of data (for example: after sending
+ * full response header or full response message).
+ * If flushing IS NOT possible than MHD activates no buffering (no
+ * delay sending) when it going to send formed fully completed logical
+ * part of data and activate normal buffering after sending.
+ * For idled keep-alive connection MHD always activate normal
+ * buffering.
+ *
+ * @param connection connection to check
+ * @return true if force push is possible, false otherwise
+ */
+static bool
+socket_flush_possible (struct MHD_Connection *connection)
+{
+ (void) connection; /* Mute compiler warning. */
+#if defined(TCP_CORK) || defined(TCP_PUSH)
+ return true;
+#else /* !TCP_CORK && !TCP_PUSH */
+ return false;
+#endif /* !TCP_CORK && !TCP_PUSH */
+}
+
+
+/**
+ * Activate extra buffering mode on connection socket to prevent
+ * sending of partial packets.
+ *
+ * @param connection connection to be processed
+ * @return true on success, false otherwise
+ */
+static bool
+socket_start_extra_buffering (struct MHD_Connection *connection)
+{
+ bool res = false;
+ (void) connection; /* Mute compiler warning. */
+#if defined(TCP_CORK) || defined(TCP_NOPUSH)
+ const MHD_SCKT_OPT_BOOL_ on_val = 1;
+#if defined(TCP_NODELAY)
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+#endif /* TCP_NODELAY */
+ mhd_assert (NULL != connection);
+#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
+ /* Buffer data before sending */
+ res = (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NOPUSH,
+ (const void *) &on_val,
+ sizeof (on_val)))
+ ? true : false;
+#if defined(TCP_NODELAY)
+ /* Enable Nagle's algorithm */
+ /* TCP_NODELAY may interfere with TCP_NOPUSH */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+#endif /* TCP_NODELAY */
+#else /* TCP_CORK */
+#if defined(TCP_NODELAY)
+ /* Enable Nagle's algorithm */
+ /* TCP_NODELAY may prevent enabling TCP_CORK. Resulting buffering mode depends
+ solely on TCP_CORK result, so ignoring return code here. */
+ (void) setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) &off_val,
+ sizeof (off_val));
+#endif /* TCP_NODELAY */
+ /* Send only full packets */
+ res = (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_CORK,
+ (const void *) &on_val,
+ sizeof (on_val)))
+ ? true : false;
+#endif /* TCP_CORK */
+#endif /* TCP_CORK || TCP_NOPUSH */
+ return res;
+}
+
+
+/**
+ * Activate no buffering mode (no delay sending) on connection socket.
+ *
+ * @param connection connection to be processed
+ * @return true on success, false otherwise
+ */
+static bool
+socket_start_no_buffering (struct MHD_Connection *connection)
+{
+#if defined(TCP_NODELAY)
+ bool res = true;
+ const MHD_SCKT_OPT_BOOL_ on_val = 1;
+#if defined(TCP_CORK) || defined(TCP_NOPUSH)
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+#endif /* TCP_CORK || TCP_NOPUSH */
+
+ (void) connection; /* Mute compiler warning. */
+ mhd_assert (NULL != connection);
+#if defined(TCP_CORK)
+ /* Allow partial packets */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_CORK,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+#endif /* TCP_CORK */
+#if defined(TCP_NODELAY)
+ /* Disable Nagle's algorithm for sending packets without delay */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) &on_val,
+ sizeof (on_val)))
+ ? true : false;
+#endif /* TCP_NODELAY */
+#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
+ /* Disable extra buffering */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NOPUSH,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+#endif /* TCP_NOPUSH && !TCP_CORK */
+ return res;
+#else /* !TCP_NODELAY */
+ return false;
+#endif /* !TCP_NODELAY */
+}
+
+
+/**
+ * Activate no buffering mode (no delay sending) on connection socket
+ * and push to client data pending in socket buffer.
+ *
+ * @param connection connection to be processed
+ * @return true on success, false otherwise
+ */
+static bool
+socket_start_no_buffering_flush (struct MHD_Connection *connection)
+{
+ bool res = true;
+#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
+ const int dummy = 0;
+#endif /* !TCP_CORK */
+
+ if (NULL == connection)
+ return false; /* FIXME: use MHD_NONNULL? */
+ res = socket_start_no_buffering (connection);
+#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
+ /* Force flush data with zero send otherwise Darwin and some BSD systems
+ will add 5 seconds delay. Not required with TCP_CORK as switching off
+ TCP_CORK always flushes socket buffer. */
+ res &= (0 <= MHD_send_ (connection->socket_fd,
+ &dummy,
+ 0))
+ ? true : false;
+#endif /* TCP_NOPUSH && !TCP_CORK*/
+ return res;
+}
+
+
+/**
+ * Activate normal buffering mode on connection socket.
+ *
+ * @param connection connection to be processed
+ * @return true on success, false otherwise
+ */
+static bool
+socket_start_normal_buffering (struct MHD_Connection *connection)
+{
+#if defined(TCP_NODELAY)
+ bool res = true;
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+#if defined(TCP_CORK)
+ MHD_SCKT_OPT_BOOL_ cork_val = 0;
+ socklen_t param_size = sizeof (cork_val);
+#endif /* TCP_CORK */
+
+ mhd_assert (NULL != connection);
+#if defined(TCP_CORK)
+ /* Allow partial packets */
+ /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before
+ so try to check current value of TCP_CORK to prevent unrequested flushing */
+ if ( (0 != getsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_CORK,
+ (void*) &cork_val,
+ ¶m_size)) ||
+ (0 != cork_val))
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_CORK,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+#elif defined(TCP_NOPUSH)
+ /* Disable extra buffering */
+ /* No need to check current value as disabling TCP_NOPUSH will not flush partial
+ packet if TCP_NOPUSH wasn't enabled before */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NOPUSH,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+#endif /* TCP_NOPUSH && !TCP_CORK */
+ /* Enable Nagle's algorithm for normal buffering */
+ res &= (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) &off_val,
+ sizeof (off_val)))
+ ? true : false;
+ return res;
+#else /* !TCP_NODELAY */
+ return false;
+#endif /* !TCP_NODELAY */
+}
+
+
+/**
+ * Do we (still) need to send a 100 continue
+ * message for this request?
+ *
+ * @param request the request to test
+ * @return false if we don't need 100 CONTINUE, true if we do
+ */
+static bool
+need_100_continue (struct MHD_Request *request)
+{
+ const char *expect;
+
+ return ( (NULL == request->response) &&
+ (NULL != request->version_s) &&
+ (MHD_str_equal_caseless_ (request->version_s,
+ MHD_HTTP_VERSION_1_1)) &&
+ (NULL != (expect = MHD_request_lookup_value (request,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_EXPECT)))
+ &&
+ (MHD_str_equal_caseless_ (expect,
+ "100-continue")) &&
+ (request->continue_message_write_offset <
+ MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) );
+}
+
+
+/**
+ * Parse the cookie header (see RFC 2109).
+ *
+ * @param request request to parse header of
+ * @return true for success, false for failure (malformed, out of memory)
+ */
+static int
+parse_cookie_header (struct MHD_Request *request)
+{
+ const char *hdr;
+ char *cpy;
+ char *pos;
+ char *sce;
+ char *semicolon;
+ char *equals;
+ char *ekill;
+ char old;
+ int quotes;
+
+ hdr = MHD_request_lookup_value (request,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_COOKIE);
+ if (NULL == hdr)
+ return true;
+ cpy = MHD_pool_allocate (request->connection->pool,
+ strlen (hdr) + 1,
+ MHD_YES);
+ if (NULL == cpy)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (request->daemon,
+ MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
+ _ ("Not enough memory in pool to parse cookies!\n"));
+#endif
+ transmit_error_response (request,
+ MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return false;
+ }
+ memcpy (cpy,
+ hdr,
+ strlen (hdr) + 1);
+ pos = cpy;
+ while (NULL != pos)
+ {
+ while (' ' == *pos)
+ pos++; /* skip spaces */
+
+ sce = pos;
+ while ( ((*sce) != '\0') &&
+ ((*sce) != ',') &&
+ ((*sce) != ';') &&
+ ((*sce) != '=') )
+ sce++;
+ /* remove tailing whitespace (if any) from key */
+ ekill = sce - 1;
+ while ( (*ekill == ' ') &&
+ (ekill >= pos) )
+ *(ekill--) = '\0';
+ old = *sce;
+ *sce = '\0';
+ if (old != '=')
+ {
+ /* value part omitted, use empty string... */
+ if (! request_add_header (request,
+ pos,
+ "",
+ MHD_COOKIE_KIND))
+ return false;
+ if (old == '\0')
+ break;
+ pos = sce + 1;
+ continue;
+ }
+ equals = sce + 1;
+ quotes = 0;
+ semicolon = equals;
+ while ( ('\0' != semicolon[0]) &&
+ ( (0 != quotes) ||
+ ( (';' != semicolon[0]) &&
+ (',' != semicolon[0]) ) ) )
+ {
+ if ('"' == semicolon[0])
+ quotes = (quotes + 1) & 1;
+ semicolon++;
+ }
+ if ('\0' == semicolon[0])
+ semicolon = NULL;
+ if (NULL != semicolon)
+ {
+ semicolon[0] = '\0';
+ semicolon++;
+ }
+ /* remove quotes */
+ if ( ('"' == equals[0]) &&
+ ('"' == equals[strlen (equals) - 1]) )
+ {
+ equals[strlen (equals) - 1] = '\0';
+ equals++;
+ }
+ if (! request_add_header (request,
+ pos,
+ equals,
+ MHD_COOKIE_KIND))
+ return false;
+ pos = semicolon;
+ }
+ return true;
+}
+
+
+/**
+ * Parse the various headers; figure out the size
+ * of the upload and make sure the headers follow
+ * the protocol. Advance to the appropriate state.
+ *
+ * @param request request we're processing
+ */
+static void
+parse_request_headers (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ const char *clen;
+ struct MHD_Response *response;
+ const char *enc;
+ const char *end;
+
+ parse_cookie_header (request); /* FIXME: return value ignored! */
+ if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) &&
+ (NULL != request->version_s) &&
+ (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
+ request->version_s)) &&
+ (NULL ==
+ MHD_request_lookup_value (request,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_HOST)) )
+ {
+ /* die, http 1.1 request without host and we are pedantic */
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ connection->read_closed = true;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_HOST_HEADER_MISSING,
+ _ ("Received HTTP 1.1 request without `Host' header.\n"));
+#endif
+ mhd_assert (NULL == request->response);
+ response =
+ MHD_response_from_buffer (MHD_HTTP_BAD_REQUEST,
+ MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST),
+ REQUEST_LACKS_HOST,
+ MHD_RESPMEM_PERSISTENT);
+ request->response = response;
+ // FIXME: state machine advance?
+ return;
+ }
+
+ request->remaining_upload_size = 0;
+ enc = MHD_request_lookup_value (request,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING);
+ if (NULL != enc)
+ {
+ request->remaining_upload_size = MHD_SIZE_UNKNOWN;
+ if (MHD_str_equal_caseless_ (enc,
+ "chunked"))
+ request->have_chunked_upload = true;
+ return;
+ }
+ clen = MHD_request_lookup_value (request,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONTENT_LENGTH);
+ if (NULL == clen)
+ return;
+ end = clen + MHD_str_to_uint64_ (clen,
+ &request->remaining_upload_size);
+ if ( (clen == end) ||
+ ('\0' != *end) )
+ {
+ request->remaining_upload_size = 0;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (request->daemon,
+ MHD_SC_CONTENT_LENGTH_MALFORMED,
+ "Failed to parse `Content-Length' header. Closing connection.\n");
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONTENT_LENGTH_MALFORMED,
+ NULL);
+ }
+}
+
+
+/**
+ * Call the handler of the application for this
+ * request.
+ *
+ * @param request request we're processing
+ */
+static void
+call_request_handler (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ const struct MHD_Action *action;
+
+ if (NULL != request->response)
+ return; /* already queued a response */
+ if (NULL == (action =
+ daemon->rc (daemon->rc_cls,
+ request,
+ request->url,
+ request->method)))
+ {
+ /* serious internal error, close connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
+ _ (
+ "Application reported internal error, closing connection.\n"));
+ return;
+ }
+ action->action (action->action_cls,
+ request);
+}
+
+
+/**
+ * Call the handler of the application for this request. Handles
+ * chunking of the upload as well as normal uploads.
+ *
+ * @param request request we're processing
+ */
+static void
+process_request_body (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ size_t available;
+ bool instant_retry;
+ char *buffer_head;
+
+ if (NULL != request->response)
+ return; /* already queued a response */
+
+ buffer_head = request->read_buffer;
+ available = request->read_buffer_offset;
+ do
+ {
+ size_t to_be_processed;
+ size_t left_unprocessed;
+ size_t processed_size;
+
+ instant_retry = false;
+ if ( (request->have_chunked_upload) &&
+ (MHD_SIZE_UNKNOWN == request->remaining_upload_size) )
+ {
+ if ( (request->current_chunk_offset == request->current_chunk_size) &&
+ (0LLU != request->current_chunk_offset) &&
+ (available >= 2) )
+ {
+ size_t i;
+
+ /* skip new line at the *end* of a chunk */
+ i = 0;
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ i++; /* skip 1st part of line feed */
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ i++; /* skip 2nd part of line feed */
+ if (0 == i)
+ {
+ /* malformed encoding */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CHUNKED_ENCODING_MALFORMED,
+ _ (
+ "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
+ return;
+ }
+ available -= i;
+ buffer_head += i;
+ request->current_chunk_offset = 0;
+ request->current_chunk_size = 0;
+ }
+ if (request->current_chunk_offset <
+ request->current_chunk_size)
+ {
+ uint64_t cur_chunk_left;
+
+ /* we are in the middle of a chunk, give
+ as much as possible to the client (without
+ crossing chunk boundaries) */
+ cur_chunk_left
+ = request->current_chunk_size - request->current_chunk_offset;
+ if (cur_chunk_left > available)
+ {
+ to_be_processed = available;
+ }
+ else
+ { /* cur_chunk_left <= (size_t)available */
+ to_be_processed = (size_t) cur_chunk_left;
+ if (available > to_be_processed)
+ instant_retry = true;
+ }
+ }
+ else
+ {
+ size_t i;
+ size_t end_size;
+ bool malformed;
+
+ /* we need to read chunk boundaries */
+ i = 0;
+ while (i < available)
+ {
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) ||
+ (';' == buffer_head[i]) )
+ break;
+ i++;
+ if (i >= 16)
+ break;
+ }
+ end_size = i;
+ /* find beginning of CRLF (skip over chunk extensions) */
+ if (';' == buffer_head[i])
+ {
+ while (i < available)
+ {
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ break;
+ i++;
+ }
+ }
+ /* take '\n' into account; if '\n' is the unavailable
+ character, we will need to wait until we have it
+ before going further */
+ if ( (i + 1 >= available) &&
+ ! ( (1 == i) &&
+ (2 == available) &&
+ ('0' == buffer_head[0]) ) )
+ break; /* need more data... */
+ i++;
+ malformed = (end_size >= 16);
+ if (! malformed)
+ {
+ size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head,
+ end_size,
+ &request->current_chunk_size);
+ malformed = (end_size != num_dig);
+ }
+ if (malformed)
+ {
+ /* malformed encoding */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CHUNKED_ENCODING_MALFORMED,
+ _ (
+ "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
+ return;
+ }
+ /* skip 2nd part of line feed */
+ if ( (i < available) &&
+ ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) ) )
+ i++;
+
+ buffer_head += i;
+ available -= i;
+ request->current_chunk_offset = 0;
+
+ if (available > 0)
+ instant_retry = true;
+ if (0LLU == request->current_chunk_size)
+ {
+ request->remaining_upload_size = 0;
+ break;
+ }
+ continue;
+ }
+ }
+ else
+ {
+ /* no chunked encoding, give all to the client */
+ if ( (0 != request->remaining_upload_size) &&
+ (MHD_SIZE_UNKNOWN != request->remaining_upload_size) &&
+ (request->remaining_upload_size < available) )
+ {
+ to_be_processed = (size_t) request->remaining_upload_size;
+ }
+ else
+ {
+ /**
+ * 1. no chunked encoding, give all to the client
+ * 2. client may send large chunked data, but only a smaller part is available at one time.
+ */
+ to_be_processed = available;
+ }
+ }
+ left_unprocessed = to_be_processed;
+#if FIXME_OLD_STYLE
+ if (MHD_NO ==
+ daemon->rc (daemon->rc_cls,
+ request,
+ request->url,
+ request->method,
+ request->version,
+ buffer_head,
+ &left_unprocessed,
+ &request->client_context))
+ {
+ /* serious internal error, close connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
+ _ (
+ "Application reported internal error, closing connection.\n"));
+ return;
+ }
+#endif
+ if (left_unprocessed > to_be_processed)
+ mhd_panic (mhd_panic_cls,
+ __FILE__,
+ __LINE__
+#ifdef HAVE_MESSAGES
+ , _ ("libmicrohttpd API violation.\n")
+#else
+ , NULL
+#endif
+ );
+ if (0 != left_unprocessed)
+ {
+ instant_retry = false; /* client did not process everything */
+#ifdef HAVE_MESSAGES
+ /* client did not process all upload data, complain if
+ the setup was incorrect, which may prevent us from
+ handling the rest of the request */
+ if ( (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) &&
+ (! connection->suspended) )
+ MHD_DLOG (daemon,
+ MHD_SC_APPLICATION_HUNG_CONNECTION,
+ _ (
+ "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
+#endif
+ }
+ processed_size = to_be_processed - left_unprocessed;
+ if (request->have_chunked_upload)
+ request->current_chunk_offset += processed_size;
+ /* dh left "processed" bytes in buffer for next time... */
+ buffer_head += processed_size;
+ available -= processed_size;
+ if (MHD_SIZE_UNKNOWN != request->remaining_upload_size)
+ request->remaining_upload_size -= processed_size;
+ }
+ while (instant_retry);
+ if (available > 0)
+ memmove (request->read_buffer,
+ buffer_head,
+ available);
+ request->read_buffer_offset = available;
+}
+
+
+/**
+ * Clean up the state of the given connection and move it into the
+ * clean up queue for final disposal.
+ * @remark To be called only from thread that process connection's
+ * recv(), send() and response.
+ *
+ * @param connection handle for the connection to clean up
+ */
+static void
+cleanup_connection (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ if (connection->request.in_cleanup)
+ return; /* Prevent double cleanup. */
+ connection->request.in_cleanup = true;
+ if (NULL != connection->request.response)
+ {
+ MHD_response_queue_for_destroy (connection->request.response);
+ connection->request.response = NULL;
+ }
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ if (connection->suspended)
+ {
+ DLL_remove (daemon->suspended_connections_head,
+ daemon->suspended_connections_tail,
+ connection);
+ connection->suspended = false;
+ }
+ else
+ {
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ {
+ if (connection->connection_timeout ==
+ daemon->connection_default_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ DLL_remove (daemon->connections_head,
+ daemon->connections_tail,
+ connection);
+ }
+ DLL_insert (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ connection);
+ connection->resuming = false;
+ connection->request.in_idle = false;
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ {
+ /* if we were at the connection limit before and are in
+ thread-per-connection mode, signal the main thread
+ to resume accepting connections */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc,
+ "c")) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_USE_FAILED,
+ _ (
+ "Failed to signal end of connection via inter-thread communication channel.\n"));
+#endif
+ }
+ }
+}
+
+
+#ifdef EPOLL_SUPPORT
+/**
+ * Perform epoll() processing, possibly moving the connection back into
+ * the epoll() set if needed.
+ *
+ * @param connection connection to process
+ * @return true if we should continue to process the
+ * connection (not dead yet), false if it died
+ */
+static bool
+connection_epoll_update_ (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
+ ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) ||
+ ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) )
+ {
+ /* add to epoll set */
+ struct epoll_event event;
+
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = connection;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ connection->socket_fd,
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ connection->request.state = MHD_REQUEST_CLOSED;
+ cleanup_connection (connection);
+ return false;
+ }
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ return true;
+}
+
+
+#endif
+
+
+/**
+ * Update the 'event_loop_info' field of this connection based on the
+ * state that the connection is now in. May also close the connection
+ * or perform other updates to the connection if needed to prepare for
+ * the next round of the event loop.
+ *
+ * @param connection connection to get poll set for
+ */
+static void
+connection_update_event_loop_info (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+ struct MHD_Request *request = &connection->request;
+
+ /* Do not update states of suspended connection */
+ if (connection->suspended)
+ return; /* States will be updated after resume. */
+#ifdef HTTPS_SUPPORT
+ {
+ struct MHD_TLS_Plugin *tls;
+
+ if ( (NULL != (tls = daemon->tls_api)) &&
+ (tls->update_event_loop_info (tls->cls,
+ connection->tls_cs,
+ &request->event_loop_info)) )
+ return; /* TLS has decided what to do */
+ }
+#endif /* HTTPS_SUPPORT */
+ while (1)
+ {
+#if DEBUG_STATES
+ MHD_DLOG (daemon,
+ MHD_SC_STATE_MACHINE_STATUS_REPORT,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (request->state));
+#endif
+ switch (request->state)
+ {
+ case MHD_REQUEST_INIT:
+ case MHD_REQUEST_URL_RECEIVED:
+ case MHD_REQUEST_HEADER_PART_RECEIVED:
+ /* while reading headers, we always grow the
+ read buffer if needed, no size-check required */
+ if ( (request->read_buffer_offset == request->read_buffer_size) &&
+ (! try_grow_read_buffer (request)) )
+ {
+ transmit_error_response (request,
+ MHD_SC_CLIENT_HEADER_TOO_BIG,
+ (NULL != request->url)
+ ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
+ : MHD_HTTP_URI_TOO_LONG,
+ REQUEST_TOO_BIG);
+ continue;
+ }
+ if (! connection->read_closed)
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_REQUEST_HEADERS_RECEIVED:
+ mhd_assert (0);
+ break;
+ case MHD_REQUEST_HEADERS_PROCESSED:
+ mhd_assert (0);
+ break;
+ case MHD_REQUEST_CONTINUE_SENDING:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_REQUEST_CONTINUE_SENT:
+ if (request->read_buffer_offset == request->read_buffer_size)
+ {
+ if ( (! try_grow_read_buffer (request)) &&
+ (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
+ {
+ /* failed to grow the read buffer, and the client
+ which is supposed to handle the received data in
+ a *blocking* fashion (in this mode) did not
+ handle the data as it was supposed to!
+
+ => we would either have to do busy-waiting
+ (on the client, which would likely fail),
+ or if we do nothing, we would just timeout
+ on the connection (if a timeout is even set!).
+
+ Solution: we kill the connection with an error */transmit_error_response (request,
+ MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ INTERNAL_ERROR);
+ continue;
+ }
+ }
+ if ( (request->read_buffer_offset < request->read_buffer_size) &&
+ (! connection->read_closed) )
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_REQUEST_BODY_RECEIVED:
+ case MHD_REQUEST_FOOTER_PART_RECEIVED:
+ /* while reading footers, we always grow the
+ read buffer if needed, no size-check required */
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+ NULL);
+ continue;
+ }
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ /* transition to FOOTERS_RECEIVED
+ happens in read handler */
+ break;
+ case MHD_REQUEST_FOOTERS_RECEIVED:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_REQUEST_HEADERS_SENDING:
+ /* headers in buffer, keep writing */
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_REQUEST_HEADERS_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_REQUEST_NORMAL_BODY_READY:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_REQUEST_NORMAL_BODY_UNREADY:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_REQUEST_CHUNKED_BODY_READY:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_REQUEST_CHUNKED_BODY_UNREADY:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_REQUEST_BODY_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_REQUEST_FOOTERS_SENDING:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_REQUEST_FOOTERS_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_REQUEST_CLOSED:
+ request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+ return; /* do nothing, not even reading */
+#ifdef UPGRADE_SUPPORT
+ case MHD_REQUEST_UPGRADE:
+ mhd_assert (0);
+ break;
+#endif /* UPGRADE_SUPPORT */
+ default:
+ mhd_assert (0);
+ }
+ break;
+ }
+}
+
+
+/**
+ * This function was created to handle per-request processing that
+ * has to happen even if the socket cannot be read or written to.
+ * @remark To be called only from thread that process request's
+ * recv(), send() and response.
+ *
+ * @param request the request to handle
+ * @return true if we should continue to process the
+ * request (not dead yet), false if it died
+ */
+bool
+MHD_request_handle_idle_ (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ struct MHD_Connection *connection = request->connection;
+ char *line;
+ size_t line_len;
+ bool ret;
+
+ request->in_idle = true;
+ while (! connection->suspended)
+ {
+#ifdef HTTPS_SUPPORT
+ struct MHD_TLS_Plugin *tls;
+
+ if ( (NULL != (tls = daemon->tls_api)) &&
+ (! tls->idle_ready (tls->cls,
+ connection->tls_cs)) )
+ break;
+#endif /* HTTPS_SUPPORT */
+#if DEBUG_STATES
+ MHD_DLOG (daemon,
+ MHD_SC_STATE_MACHINE_STATUS_REPORT,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (request->state));
+#endif
+ switch (request->state)
+ {
+ case MHD_REQUEST_INIT:
+ line = get_next_header_line (request,
+ &line_len);
+ /* Check for empty string, as we might want
+ to tolerate 'spurious' empty lines; also
+ NULL means we didn't get a full line yet;
+ line is not 0-terminated here. */
+ if ( (NULL == line) ||
+ (0 == line[0]) )
+ {
+ if (MHD_REQUEST_INIT != request->state)
+ continue;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+ NULL);
+ continue;
+ }
+ break;
+ }
+ if (MHD_NO ==
+ parse_initial_message_line (request,
+ line,
+ line_len))
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_CLOSED,
+ NULL);
+ else
+ request->state = MHD_REQUEST_URL_RECEIVED;
+ continue;
+ case MHD_REQUEST_URL_RECEIVED:
+ line = get_next_header_line (request,
+ NULL);
+ if (NULL == line)
+ {
+ if (MHD_REQUEST_URL_RECEIVED != request->state)
+ continue;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+ NULL);
+ continue;
+ }
+ break;
+ }
+ if (0 == line[0])
+ {
+ request->state = MHD_REQUEST_HEADERS_RECEIVED;
+ request->header_size = (size_t) (line - request->read_buffer);
+ continue;
+ }
+ if (! process_header_line (request,
+ line))
+ {
+ transmit_error_response (request,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ break;
+ }
+ request->state = MHD_REQUEST_HEADER_PART_RECEIVED;
+ continue;
+ case MHD_REQUEST_HEADER_PART_RECEIVED:
+ line = get_next_header_line (request,
+ NULL);
+ if (NULL == line)
+ {
+ if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED)
+ continue;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+ NULL);
+ continue;
+ }
+ break;
+ }
+ if (MHD_NO ==
+ process_broken_line (request,
+ line,
+ MHD_HEADER_KIND))
+ continue;
+ if (0 == line[0])
+ {
+ request->state = MHD_REQUEST_HEADERS_RECEIVED;
+ request->header_size = (size_t) (line - request->read_buffer);
+ continue;
+ }
+ continue;
+ case MHD_REQUEST_HEADERS_RECEIVED:
+ parse_request_headers (request);
+ if (MHD_REQUEST_CLOSED == request->state)
+ continue;
+ request->state = MHD_REQUEST_HEADERS_PROCESSED;
+ if (connection->suspended)
+ break;
+ continue;
+ case MHD_REQUEST_HEADERS_PROCESSED:
+ call_request_handler (request); /* first call */
+ if (MHD_REQUEST_CLOSED == request->state)
+ continue;
+ if (need_100_continue (request))
+ {
+ request->state = MHD_REQUEST_CONTINUE_SENDING;
+ if (socket_flush_possible (connection))
+ socket_start_extra_buffering (connection);
+ else
+ socket_start_no_buffering (connection);
+ break;
+ }
+ if ( (NULL != request->response) &&
+ ( (MHD_METHOD_POST == request->method) ||
+ (MHD_METHOD_PUT == request->method) ) )
+ {
+ /* we refused (no upload allowed!) */
+ request->remaining_upload_size = 0;
+ /* force close, in case client still tries to upload... */
+ connection->read_closed = true;
+ }
+ request->state = (0 == request->remaining_upload_size)
+ ? MHD_REQUEST_FOOTERS_RECEIVED
+ : MHD_REQUEST_CONTINUE_SENT;
+ if (connection->suspended)
+ break;
+ continue;
+ case MHD_REQUEST_CONTINUE_SENDING:
+ if (request->continue_message_write_offset ==
+ MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE))
+ {
+ request->state = MHD_REQUEST_CONTINUE_SENT;
+ if (! socket_flush_possible (connection))
+ socket_start_no_buffering_flush (connection);
+ else
+ socket_start_normal_buffering (connection);
+ continue;
+ }
+ break;
+ case MHD_REQUEST_CONTINUE_SENT:
+ if (0 != request->read_buffer_offset)
+ {
+ process_request_body (request); /* loop call */
+ if (MHD_REQUEST_CLOSED == request->state)
+ continue;
+ }
+ if ( (0 == request->remaining_upload_size) ||
+ ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) &&
+ (0 == request->read_buffer_offset) &&
+ (connection->read_closed) ) )
+ {
+ if ( (request->have_chunked_upload) &&
+ (! connection->read_closed) )
+ request->state = MHD_REQUEST_BODY_RECEIVED;
+ else
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ if (connection->suspended)
+ break;
+ continue;
+ }
+ break;
+ case MHD_REQUEST_BODY_RECEIVED:
+ line = get_next_header_line (request,
+ NULL);
+ if (NULL == line)
+ {
+ if (request->state != MHD_REQUEST_BODY_RECEIVED)
+ continue;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_CLOSED,
+ NULL);
+ continue;
+ }
+ break;
+ }
+ if (0 == line[0])
+ {
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ if (connection->suspended)
+ break;
+ continue;
+ }
+ if (MHD_NO == process_header_line (request,
+ line))
+ {
+ transmit_error_response (request,
+ MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ break;
+ }
+ request->state = MHD_REQUEST_FOOTER_PART_RECEIVED;
+ continue;
+ case MHD_REQUEST_FOOTER_PART_RECEIVED:
+ line = get_next_header_line (request,
+ NULL);
+ if (NULL == line)
+ {
+ if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED)
+ continue;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_CLOSED,
+ NULL);
+ continue;
+ }
+ break;
+ }
+ if (MHD_NO ==
+ process_broken_line (request,
+ line,
+ MHD_FOOTER_KIND))
+ continue;
+ if (0 == line[0])
+ {
+ request->state = MHD_REQUEST_FOOTERS_RECEIVED;
+ if (connection->suspended)
+ break;
+ continue;
+ }
+ continue;
+ case MHD_REQUEST_FOOTERS_RECEIVED:
+ call_request_handler (request); /* "final" call */
+ if (request->state == MHD_REQUEST_CLOSED)
+ continue;
+ if (NULL == request->response)
+ break; /* try again next time */
+ if (! build_header_response (request))
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
+ _ (
+ "Closing connection (failed to create response header).\n"));
+ continue;
+ }
+ request->state = MHD_REQUEST_HEADERS_SENDING;
+ if (MHD_NO != socket_flush_possible (connection))
+ socket_start_extra_buffering (connection);
+ else
+ socket_start_no_buffering (connection);
+
+ break;
+ case MHD_REQUEST_HEADERS_SENDING:
+ /* no default action */
+ break;
+ case MHD_REQUEST_HEADERS_SENT:
+ /* Some clients may take some actions right after header receive */
+ if (MHD_NO != socket_flush_possible (connection))
+ socket_start_no_buffering_flush (connection);
+
+#ifdef UPGRADE_SUPPORT
+ if (NULL != request->response->upgrade_handler)
+ {
+ socket_start_normal_buffering (connection);
+ request->state = MHD_REQUEST_UPGRADE;
+#if FIXME_LEGACY_STYLE
+ /* This request is "upgraded". Pass socket to application. */
+ if (! MHD_response_execute_upgrade_ (request->response,
+ request))
+ {
+ /* upgrade failed, fail hard */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_CONNECTION_CLOSED,
+ NULL);
+ continue;
+ }
+#endif
+ /* Response is not required anymore for this request. */
+ {
+ struct MHD_Response *const resp = request->response;
+
+ request->response = NULL;
+ MHD_response_queue_for_destroy (resp);
+ }
+ continue;
+ }
+#endif /* UPGRADE_SUPPORT */
+ if (MHD_NO != socket_flush_possible (connection))
+ socket_start_extra_buffering (connection);
+ else
+ socket_start_normal_buffering (connection);
+
+ if (request->have_chunked_upload)
+ request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY;
+ else
+ request->state = MHD_REQUEST_NORMAL_BODY_UNREADY;
+ continue;
+ case MHD_REQUEST_NORMAL_BODY_READY:
+ /* nothing to do here */
+ break;
+ case MHD_REQUEST_NORMAL_BODY_UNREADY:
+ if (NULL != request->response->crc)
+ MHD_mutex_lock_chk_ (&request->response->mutex);
+ if (0 == request->response->total_size)
+ {
+ if (NULL != request->response->crc)
+ MHD_mutex_unlock_chk_ (&request->response->mutex);
+ request->state = MHD_REQUEST_BODY_SENT;
+ continue;
+ }
+ if (try_ready_normal_body (request))
+ {
+ if (NULL != request->response->crc)
+ MHD_mutex_unlock_chk_ (&request->response->mutex);
+ request->state = MHD_REQUEST_NORMAL_BODY_READY;
+ /* Buffering for flushable socket was already enabled*/
+ if (MHD_NO == socket_flush_possible (connection))
+ socket_start_no_buffering (connection);
+ break;
+ }
+ /* mutex was already unlocked by "try_ready_normal_body */
+ /* not ready, no socket action */
+ break;
+ case MHD_REQUEST_CHUNKED_BODY_READY:
+ /* nothing to do here */
+ break;
+ case MHD_REQUEST_CHUNKED_BODY_UNREADY:
+ if (NULL != request->response->crc)
+ MHD_mutex_lock_chk_ (&request->response->mutex);
+ if ( (0 == request->response->total_size) ||
+ (request->response_write_position ==
+ request->response->total_size) )
+ {
+ if (NULL != request->response->crc)
+ MHD_mutex_unlock_chk_ (&request->response->mutex);
+ request->state = MHD_REQUEST_BODY_SENT;
+ continue;
+ }
+ if (try_ready_chunked_body (request))
+ {
+ if (NULL != request->response->crc)
+ MHD_mutex_unlock_chk_ (&request->response->mutex);
+ request->state = MHD_REQUEST_CHUNKED_BODY_READY;
+ /* Buffering for flushable socket was already enabled */
+ if (MHD_NO == socket_flush_possible (connection))
+ socket_start_no_buffering (connection);
+ continue;
+ }
+ /* mutex was already unlocked by try_ready_chunked_body */
+ break;
+ case MHD_REQUEST_BODY_SENT:
+ if (! build_header_response (request))
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (connection,
+ MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
+ _ (
+ "Closing connection (failed to create response header).\n"));
+ continue;
+ }
+ if ( (! request->have_chunked_upload) ||
+ (request->write_buffer_send_offset ==
+ request->write_buffer_append_offset) )
+ request->state = MHD_REQUEST_FOOTERS_SENT;
+ else
+ request->state = MHD_REQUEST_FOOTERS_SENDING;
+ continue;
+ case MHD_REQUEST_FOOTERS_SENDING:
+ /* no default action */
+ break;
+ case MHD_REQUEST_FOOTERS_SENT:
+ {
+ struct MHD_Response *response = request->response;
+
+ if (MHD_HTTP_PROCESSING == response->status_code)
+ {
+ /* After this type of response, we allow sending another! */
+ request->state = MHD_REQUEST_HEADERS_PROCESSED;
+ MHD_response_queue_for_destroy (response);
+ request->response = NULL;
+ /* FIXME: maybe partially reset memory pool? */
+ continue;
+ }
+ if (socket_flush_possible (connection))
+ socket_start_no_buffering_flush (connection);
+ else
+ socket_start_normal_buffering (connection);
+
+ if (NULL != response->termination_cb)
+ {
+ response->termination_cb (response->termination_cb_cls,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK,
+ request->client_context);
+ }
+ MHD_response_queue_for_destroy (response);
+ request->response = NULL;
+ }
+ if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) ||
+ (connection->read_closed) )
+ {
+ /* have to close for some reason */
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ MHD_pool_destroy (connection->pool);
+ connection->pool = NULL;
+ request->read_buffer = NULL;
+ request->read_buffer_size = 0;
+ request->read_buffer_offset = 0;
+ }
+ else
+ {
+ /* can try to keep-alive */
+ if (socket_flush_possible (connection))
+ socket_start_normal_buffering (connection);
+ request->version_s = NULL;
+ request->state = MHD_REQUEST_INIT;
+ request->last = NULL;
+ request->colon = NULL;
+ request->header_size = 0;
+ request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
+ /* Reset the read buffer to the starting size,
+ preserving the bytes we have already read. */
+ request->read_buffer
+ = MHD_pool_reset (connection->pool,
+ request->read_buffer,
+ request->read_buffer_offset,
+ daemon->connection_memory_limit_b / 2);
+ request->read_buffer_size
+ = daemon->connection_memory_limit_b / 2;
+ }
+ // FIXME: this is too much, NULLs out some of the things
+ // initialized above...
+ memset (request,
+ 0,
+ sizeof (struct MHD_Request));
+ request->daemon = daemon;
+ request->connection = connection;
+ continue;
+ case MHD_REQUEST_CLOSED:
+ cleanup_connection (connection);
+ request->in_idle = false;
+ return false;
+#ifdef UPGRADE_SUPPORT
+ case MHD_REQUEST_UPGRADE:
+ request->in_idle = false;
+ return true; /* keep open */
+#endif /* UPGRADE_SUPPORT */
+ default:
+ mhd_assert (0);
+ break;
+ }
+ break;
+ }
+ if (! connection->suspended)
+ {
+ time_t timeout;
+ timeout = connection->connection_timeout;
+ if ( (0 != timeout) &&
+ (timeout < (MHD_monotonic_sec_counter ()
+ - connection->last_activity)) )
+ {
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
+ request->in_idle = false;
+ return true;
+ }
+ }
+ connection_update_event_loop_info (connection);
+ ret = true;
+#ifdef EPOLL_SUPPORT
+ if ( (! connection->suspended) &&
+ (MHD_ELS_EPOLL == daemon->event_loop_syscall) )
+ {
+ ret = connection_epoll_update_ (connection);
+ }
+#endif /* EPOLL_SUPPORT */
+ request->in_idle = false;
+ return ret;
+}
+
+
+/**
+ * Call the handlers for a connection in the appropriate order based
+ * on the readiness as detected by the event loop.
+ *
+ * @param con connection to handle
+ * @param read_ready set if the socket is ready for reading
+ * @param write_ready set if the socket is ready for writing
+ * @param force_close set if a hard error was detected on the socket;
+ * if this information is not available, simply pass #MHD_NO
+ * @return #MHD_YES to continue normally,
+ * #MHD_NO if a serious error was encountered and the
+ * connection is to be closed.
+ */
+// FIXME: rename connection->request?
+int
+MHD_connection_call_handlers_ (struct MHD_Connection *con,
+ bool read_ready,
+ bool write_ready,
+ bool force_close)
+{
+ struct MHD_Daemon *daemon = con->daemon;
+ int ret;
+ bool states_info_processed = false;
+ /* Fast track flag */
+ bool on_fasttrack = (con->request.state == MHD_REQUEST_INIT);
+
+#ifdef HTTPS_SUPPORT
+ if (con->tls_read_ready)
+ read_ready = true;
+#endif /* HTTPS_SUPPORT */
+ if (! force_close)
+ {
+ if ( (MHD_EVENT_LOOP_INFO_READ ==
+ con->request.event_loop_info) &&
+ read_ready)
+ {
+ MHD_request_handle_read_ (&con->request);
+ ret = MHD_request_handle_idle_ (&con->request);
+ states_info_processed = true;
+ }
+ /* No need to check value of 'ret' here as closed connection
+ * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
+ if ( (MHD_EVENT_LOOP_INFO_WRITE ==
+ con->request.event_loop_info) &&
+ write_ready)
+ {
+ MHD_request_handle_write_ (&con->request);
+ ret = MHD_request_handle_idle_ (&con->request);
+ states_info_processed = true;
+ }
+ }
+ else
+ {
+ MHD_connection_close_ (con,
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+ return MHD_request_handle_idle_ (&con->request);
+ }
+
+ if (! states_info_processed)
+ { /* Connection is not read or write ready, but external conditions
+ * may be changed and need to be processed. */
+ ret = MHD_request_handle_idle_ (&con->request);
+ }
+ /* Fast track for fast connections. */
+ /* If full request was read by single read_handler() invocation
+ and headers were completely prepared by single MHD_request_handle_idle_()
+ then try not to wait for next sockets polling and send response
+ immediately.
+ As writeability of socket was not checked and it may have
+ some data pending in system buffers, use this optimization
+ only for non-blocking sockets. *//* No need to check 'ret' as connection is always in
+ * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */else if (on_fasttrack &&
+ con->sk_nonblck)
+ {
+ if (MHD_REQUEST_HEADERS_SENDING == con->request.state)
+ {
+ MHD_request_handle_write_ (&con->request);
+ /* Always call 'MHD_request_handle_idle_()' after each read/write. */
+ ret = MHD_request_handle_idle_ (&con->request);
+ }
+ /* If all headers were sent by single write_handler() and
+ * response body is prepared by single MHD_request_handle_idle_()
+ * call - continue. */
+ if ((MHD_REQUEST_NORMAL_BODY_READY == con->request.state) ||
+ (MHD_REQUEST_CHUNKED_BODY_READY == con->request.state))
+ {
+ MHD_request_handle_write_ (&con->request);
+ ret = MHD_request_handle_idle_ (&con->request);
+ }
+ }
+
+ /* All connection's data and states are processed for this turn.
+ * If connection already has more data to be processed - use
+ * zero timeout for next select()/poll(). */
+ /* Thread-per-connection do not need global zero timeout as
+ * connections are processed individually. */
+ /* Note: no need to check for read buffer availability for
+ * TLS read-ready connection in 'read info' state as connection
+ * without space in read buffer will be market as 'info block'. */
+ if ( (! daemon->data_already_pending) &&
+ (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
+ {
+ if (MHD_EVENT_LOOP_INFO_BLOCK ==
+ con->request.event_loop_info)
+ daemon->data_already_pending = true;
+#ifdef HTTPS_SUPPORT
+ else if ( (con->tls_read_ready) &&
+ (MHD_EVENT_LOOP_INFO_READ ==
+ con->request.event_loop_info) )
+ daemon->data_already_pending = true;
+#endif /* HTTPS_SUPPORT */
+ }
+ return ret;
+}
+
+
+/* end of connection_call_handlers.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_call_handlers.h
^
|
@@ -0,0 +1,64 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_call_handlers.h
+ * @brief function to call event handlers based on event mask
+ * @author Christian Grothoff
+ */
+
+#ifndef CONNECTION_CALL_HANDLERS_H
+#define CONNECTION_CALL_HANDLERS_H
+
+/**
+ * Call the handlers for a connection in the appropriate order based
+ * on the readiness as detected by the event loop.
+ *
+ * @param con connection to handle
+ * @param read_ready set if the socket is ready for reading
+ * @param write_ready set if the socket is ready for writing
+ * @param force_close set if a hard error was detected on the socket;
+ * if this information is not available, simply pass #MHD_NO
+ * @return #MHD_YES to continue normally,
+ * #MHD_NO if a serious error was encountered and the
+ * connection is to be closed.
+ */
+int
+MHD_connection_call_handlers_ (struct MHD_Connection *con,
+ bool read_ready,
+ bool write_ready,
+ bool force_close)
+MHD_NONNULL (1);
+
+
+/**
+ * This function was created to handle per-request processing that
+ * has to happen even if the socket cannot be read or written to.
+ * @remark To be called only from thread that process request's
+ * recv(), send() and response.
+ *
+ * @param request the request to handle
+ * @return true if we should continue to process the
+ * request (not dead yet), false if it died
+ */
+bool
+MHD_request_handle_idle_ (struct MHD_Request *request)
+MHD_NONNULL (1);
+
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_cleanup.c
^
|
@@ -0,0 +1,160 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_cleanup.c
+ * @brief function to clean up completed connections
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_cleanup.h"
+#include "daemon_ip_limit.h"
+
+
+#ifdef UPGRADE_SUPPORT
+/**
+ * Finally cleanup upgrade-related resources. It should
+ * be called when TLS buffers have been drained and
+ * application signaled MHD by #MHD_UPGRADE_ACTION_CLOSE.
+ *
+ * @param connection handle to the upgraded connection to clean
+ */
+static void
+connection_cleanup_upgraded (struct MHD_Connection *connection)
+{
+ struct MHD_UpgradeResponseHandle *urh = connection->request.urh;
+
+ if (NULL == urh)
+ return;
+#ifdef HTTPS_SUPPORT
+ /* Signal remote client the end of TLS connection by
+ * gracefully closing TLS session. */
+ {
+ struct MHD_TLS_Plugin *tls;
+
+ if (NULL != (tls = connection->daemon->tls_api))
+ (void) tls->shutdown_connection (tls->cls,
+ connection->tls_cs);
+ }
+ if (MHD_INVALID_SOCKET != urh->mhd.socket)
+ MHD_socket_close_chk_ (urh->mhd.socket);
+ if (MHD_INVALID_SOCKET != urh->app.socket)
+ MHD_socket_close_chk_ (urh->app.socket);
+#endif /* HTTPS_SUPPORT */
+ connection->request.urh = NULL;
+ free (urh);
+}
+
+
+#endif /* UPGRADE_SUPPORT */
+
+
+/**
+ * Free resources associated with all closed connections. (destroy
+ * responses, free buffers, etc.). All closed connections are kept in
+ * the "cleanup" doubly-linked list.
+ *
+ * @remark To be called only from thread that process daemon's
+ * select()/poll()/etc.
+ *
+ * @param daemon daemon to clean up
+ */
+void
+MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
+{
+ struct MHD_Connection *pos;
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ while (NULL != (pos = daemon->cleanup_tail))
+ {
+ DLL_remove (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ pos);
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+
+ if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) &&
+ (! pos->thread_joined) &&
+ (! MHD_join_thread_ (pos->pid.handle)) )
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+#ifdef UPGRADE_SUPPORT
+ connection_cleanup_upgraded (pos);
+#endif /* UPGRADE_SUPPORT */
+ MHD_pool_destroy (pos->pool);
+#ifdef HTTPS_SUPPORT
+ {
+ struct MHD_TLS_Plugin *tls;
+
+ if (NULL != (tls = daemon->tls_api))
+ tls->teardown_connection (tls->cls,
+ pos->tls_cs);
+ }
+#endif /* HTTPS_SUPPORT */
+
+ /* clean up the connection */
+ if (NULL != daemon->notify_connection_cb)
+ daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
+ pos,
+ MHD_CONNECTION_NOTIFY_CLOSED);
+ MHD_ip_limit_del (daemon,
+ (const struct sockaddr *) &pos->addr,
+ pos->addr_len);
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ if ( (-1 != daemon->epoll_fd) &&
+ (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
+ {
+ /* epoll documentation suggests that closing a FD
+ automatically removes it from the epoll set; however,
+ this is not true as if we fail to do manually remove it,
+ we are still seeing an event for this fd in epoll,
+ causing grief (use-after-free...) --- at least on my
+ system. */if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ pos->socket_fd,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ }
+#endif
+ if (NULL != pos->request.response)
+ {
+ MHD_response_queue_for_destroy (pos->request.response);
+ pos->request.response = NULL;
+ }
+ if (MHD_INVALID_SOCKET != pos->socket_fd)
+ MHD_socket_close_chk_ (pos->socket_fd);
+ free (pos);
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ daemon->connections--;
+ daemon->at_limit = false;
+ }
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+}
+
+
+/* end of connection_cleanup.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_cleanup.h
^
|
@@ -0,0 +1,42 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_cleanup.h
+ * @brief functions to cleanup completed connection
+ * @author Christian Grothoff
+ */
+#ifndef CONNECTION_CLEANUP_H
+#define CONNECTION_CLEANUP_H
+
+
+/**
+ * Free resources associated with all closed connections. (destroy
+ * responses, free buffers, etc.). All closed connections are kept in
+ * the "cleanup" doubly-linked list.
+ *
+ * @remark To be called only from thread that process daemon's
+ * select()/poll()/etc.
+ *
+ * @param daemon daemon to clean up
+ */
+void
+MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_close.c
^
|
@@ -0,0 +1,103 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_close.c
+ * @brief functions to close a connection
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_close.h"
+
+
+/**
+ * Mark connection as "closed".
+ *
+ * @remark To be called from any thread.
+ *
+ * @param connection connection to close
+ */
+void
+MHD_connection_mark_closed_ (struct MHD_Connection *connection)
+{
+ const struct MHD_Daemon *daemon = connection->daemon;
+
+ connection->request.state = MHD_REQUEST_CLOSED;
+ connection->request.event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+ if (! daemon->enable_turbo)
+ {
+#ifdef HTTPS_SUPPORT
+ struct MHD_TLS_Plugin *tls;
+
+ /* For TLS connection use shutdown of TLS layer
+ * and do not shutdown TCP socket. This give more
+ * chances to send TLS closure data to remote side.
+ * Closure of TLS layer will be interpreted by
+ * remote side as end of transmission. */if (NULL != (tls = daemon->tls_api))
+ {
+ if (MHD_YES !=
+ tls->shutdown_connection (tls->cls,
+ connection->tls_cs))
+ {
+ (void) shutdown (connection->socket_fd,
+ SHUT_WR);
+ /* FIXME: log errors */
+ }
+ }
+ else /* Combined with next 'shutdown()'. */
+#endif /* HTTPS_SUPPORT */
+ {
+ (void) shutdown (connection->socket_fd,
+ SHUT_WR); /* FIXME: log errors */
+ }
+ }
+}
+
+
+/**
+ * Close the given connection and give the specified termination code
+ * to the user.
+ *
+ * @remark To be called only from thread that process
+ * connection's recv(), send() and response.
+ *
+ * @param connection connection to close
+ * @param rtc termination reason to give
+ */
+void
+MHD_connection_close_ (struct MHD_Connection *connection,
+ enum MHD_RequestTerminationCode rtc)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+ struct MHD_Response *resp = connection->request.response;
+
+ (void) rtc; // FIXME
+ MHD_connection_mark_closed_ (connection);
+ if (NULL != resp)
+ {
+ connection->request.response = NULL;
+ MHD_response_queue_for_destroy (resp);
+ }
+ if (NULL != daemon->notify_connection_cb)
+ daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
+ connection,
+ MHD_CONNECTION_NOTIFY_CLOSED);
+}
+
+
+/* end of connection_close.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_close.h
^
|
@@ -0,0 +1,56 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_close.h
+ * @brief functions to close connection
+ * @author Christian Grothoff
+ */
+#ifndef CONNECTION_CLOSE_H
+#define CONNECTION_CLOSE_H
+
+#include "microhttpd2.h"
+
+/**
+ * Mark connection as "closed".
+ *
+ * @remark To be called from any thread.
+ *
+ * @param connection connection to close
+ */
+void
+MHD_connection_mark_closed_ (struct MHD_Connection *connection)
+MHD_NONNULL (1);
+
+
+/**
+ * Close the given connection and give the specified termination code
+ * to the user.
+ *
+ * @remark To be called only from thread that process
+ * connection's recv(), send() and response.
+ *
+ * @param connection connection to close
+ * @param rtc termination reason to give
+ */
+void
+MHD_connection_close_ (struct MHD_Connection *connection,
+ enum MHD_RequestTerminationCode rtc)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_finish_forward.c
^
|
@@ -0,0 +1,95 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_finish_forward.c
+ * @brief complete upgrade socket forwarding operation in TLS mode
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_finish_forward.h"
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Stop TLS forwarding on upgraded connection and
+ * reflect remote disconnect state to socketpair.
+ * @remark In thread-per-connection mode this function
+ * can be called from any thread, in other modes this
+ * function must be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param connection the upgraded connection
+ */
+void
+MHD_connection_finish_forward_ (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+ struct MHD_UpgradeResponseHandle *urh = connection->request.urh;
+
+ if (NULL == daemon->tls_api)
+ return; /* Nothing to do with non-TLS connection. */
+
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ DLL_remove (daemon->urh_head,
+ daemon->urh_tail,
+ urh);
+#if EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_DEL,
+ connection->socket_fd,
+ NULL)) )
+ {
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ }
+ if (urh->in_eready_list)
+ {
+ EDLL_remove (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ urh);
+ urh->in_eready_list = false;
+ }
+#endif /* EPOLL_SUPPORT */
+ if (MHD_INVALID_SOCKET != urh->mhd.socket)
+ {
+#if EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_DEL,
+ urh->mhd.socket,
+ NULL)) )
+ {
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ }
+#endif /* EPOLL_SUPPORT */
+ /* Reflect remote disconnect to application by breaking
+ * socketpair connection. */
+ shutdown (urh->mhd.socket,
+ SHUT_RDWR);
+ }
+ /* Socketpair sockets will remain open as they will be
+ * used with MHD_UPGRADE_ACTION_CLOSE. They will be
+ * closed by MHD_cleanup_upgraded_connection_() during
+ * connection's final cleanup.
+ */}
+
+
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT*/
+
+/* end of connection_finish_forward.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_finish_forward.h
^
|
@@ -0,0 +1,44 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_finish_forward.h
+ * @brief complete upgrade socket forwarding operation in TLS mode
+ * @author Christian Grothoff
+ */
+
+#ifndef CONNECTION_FINISH_FORWARD_H
+#define CONNECTION_FINISH_FORWARD_H
+
+
+/**
+ * Stop TLS forwarding on upgraded connection and
+ * reflect remote disconnect state to socketpair.
+ *
+ * @remark In thread-per-connection mode this function
+ * can be called from any thread, in other modes this
+ * function must be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param connection the upgraded connection
+ */
+void
+MHD_connection_finish_forward_ (struct MHD_Connection *connection)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_info.c
^
|
@@ -0,0 +1,111 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/connection_info.c
+ * @brief implementation of MHD_connection_get_information_sz()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Obtain information about the given connection.
+ * Use wrapper macro #MHD_connection_get_information() instead of direct use
+ * of this function.
+ *
+ * @param connection what connection to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_ConnectionInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+enum MHD_Bool
+MHD_connection_get_information_sz (struct MHD_Connection *connection,
+ enum MHD_ConnectionInformationType info_type,
+ union MHD_ConnectionInformation *return_value,
+ size_t return_value_size)
+{
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
+ switch (info_type)
+ {
+#ifdef HTTPS_SUPPORT
+ case MHD_CONNECTION_INFORMATION_CIPHER_ALGO:
+ CHECK_SIZE (int);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ // return_value->cipher_algorithm
+ // = gnutls_cipher_get (connection->tls_session);
+ return MHD_NO; // FIXME: to be implemented
+ case MHD_CONNECTION_INFORMATION_PROTOCOL:
+ CHECK_SIZE (int);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ // return_value->protocol
+ // = gnutls_protocol_get_version (connection->tls_session);
+ return MHD_NO; // FIXME: to be implemented
+ case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION:
+ CHECK_SIZE (void *);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ // return_value->tls_session = connection->tls_session;
+ return MHD_NO; // FIXME: to be implemented
+#endif /* HTTPS_SUPPORT */
+ case MHD_CONNECTION_INFORMATION_CLIENT_ADDRESS:
+ CHECK_SIZE (struct sockaddr *);
+ return_value->client_addr
+ = (const struct sockaddr *) &connection->addr;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_DAEMON:
+ CHECK_SIZE (struct MHD_Daemon *);
+ return_value->daemon = connection->daemon;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_FD:
+ CHECK_SIZE (MHD_socket);
+ return_value->connect_fd = connection->socket_fd;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT:
+ CHECK_SIZE (void **);
+ return_value->socket_context = &connection->socket_context;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED:
+ CHECK_SIZE (enum MHD_Bool);
+ return_value->suspended
+ = connection->suspended ? MHD_YES : MHD_NO;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT:
+ CHECK_SIZE (unsigned int);
+ return_value->connection_timeout
+ = (unsigned int) connection->connection_timeout;
+ return MHD_YES;
+ default:
+ return MHD_NO;
+ }
+
+#undef CHECK_SIZE
+}
+
+
+/* end of connection_info.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_options.c
^
|
@@ -0,0 +1,118 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/connection_options.c
+ * @brief functions to set per-connection options
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Set custom timeout for the given connection. Specified as the
+ * number of seconds. Use zero for no timeout. Calling this function
+ * will reset timeout timer.
+ *
+ * @param connection connection to configure timeout for
+ * @param timeout_s new timeout in seconds
+ */
+void
+MHD_connection_set_timeout (struct MHD_Connection *connection,
+ unsigned int timeout_s)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ connection->last_activity = MHD_monotonic_sec_counter ();
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ {
+ /* Simple case, no need to lock to update DLLs */
+ connection->connection_timeout = (time_t) timeout_s;
+ return;
+ }
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ if (! connection->suspended)
+ {
+ if (connection->connection_timeout ==
+ daemon->connection_default_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ connection->connection_timeout = (time_t) timeout_s;
+ if (! connection->suspended)
+ {
+ if (connection->connection_timeout ==
+ daemon->connection_default_timeout)
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_insert (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+}
+
+
+/**
+ * Update the 'last_activity' field of the connection to the current
+ * time and move the connection to the head of the 'normal_timeout'
+ * list if the timeout for the connection uses the default value.
+ *
+ * @param connection the connection that saw some activity
+ */
+void
+MHD_update_last_activity_ (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ if (0 == connection->connection_timeout)
+ return; /* Skip update of activity for connections
+ without timeout timer. */
+ if (connection->suspended)
+ return; /* no activity on suspended connections */
+
+ connection->last_activity = MHD_monotonic_sec_counter ();
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ return; /* each connection has personal timeout */
+
+ if (connection->connection_timeout !=
+ daemon->connection_default_timeout)
+ return; /* custom timeout, no need to move it in "normal" DLL */
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ /* move connection to head of timeout list (by remove + add operation) */
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+}
+
+
+/* end of connection_options.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_update_last_activity.c
^
|
@@ -0,0 +1,65 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_update_last_activity.c
+ * @brief functions to add connection to our active set
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_update_last_activity.h"
+
+
+/**
+ * Update the 'last_activity' field of the connection to the current time
+ * and move the connection to the head of the 'normal_timeout' list if
+ * the timeout for the connection uses the default value.
+ *
+ * @param connection the connection that saw some activity
+ */
+void
+MHD_connection_update_last_activity_ (struct MHD_Connection *connection)
+{
+ struct MHD_Daemon *daemon = connection->daemon;
+
+ if (0 == connection->connection_timeout)
+ return; /* Skip update of activity for connections
+ without timeout timer. */
+ if (connection->suspended)
+ return; /* no activity on suspended connections */
+
+ connection->last_activity = MHD_monotonic_sec_counter ();
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ return; /* each connection has personal timeout */
+
+ if (connection->connection_timeout != daemon->connection_default_timeout)
+ return; /* custom timeout, no need to move it in "normal" DLL */
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ /* move connection to head of timeout list (by remove + add operation) */
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+}
+
+
+/* end of connection_update_last_activity.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/connection_update_last_activity.h
^
|
@@ -0,0 +1,40 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/connection_update_last_activity.h
+ * @brief function to update last activity of a connection
+ * @author Christian Grothoff
+ */
+
+#ifndef CONNECTION_UPDATE_LAST_ACTIVITY_H
+#define CONNECTION_UPDATE_LAST_ACTIVITY_H
+
+
+/**
+ * Update the 'last_activity' field of the connection to the current time
+ * and move the connection to the head of the 'normal_timeout' list if
+ * the timeout for the connection uses the default value.
+ *
+ * @param connection the connection that saw some activity
+ */
+void
+MHD_connection_update_last_activity_ (struct MHD_Connection *connection)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_close_all_connections.c
^
|
@@ -0,0 +1,237 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_close_all_connections.c
+ * @brief function to close all connections open at a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_cleanup.h"
+#include "connection_close.h"
+#include "connection_finish_forward.h"
+#include "daemon_close_all_connections.h"
+#include "request_resume.h"
+#include "upgrade_process.h"
+
+
+/**
+ * Close the given connection, remove it from all of its
+ * DLLs and move it into the cleanup queue.
+ * @remark To be called only from thread that
+ * process daemon's select()/poll()/etc.
+ *
+ * @param pos connection to move to cleanup
+ */
+static void
+close_connection (struct MHD_Connection *pos)
+{
+ struct MHD_Daemon *daemon = pos->daemon;
+
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ {
+ MHD_connection_mark_closed_ (pos);
+ return; /* must let thread to do the rest */
+ }
+ MHD_connection_close_ (pos,
+ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
+
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+
+ mhd_assert (! pos->suspended);
+ mhd_assert (! pos->resuming);
+ if (pos->connection_timeout ==
+ pos->daemon->connection_default_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ pos);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ pos);
+ DLL_remove (daemon->connections_head,
+ daemon->connections_tail,
+ pos);
+ DLL_insert (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ pos);
+
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+}
+
+
+/**
+ * Close all connections for the daemon. Must only be called when
+ * MHD_Daemon::shutdown was set to true.
+ *
+ * @remark To be called only from thread that process daemon's
+ * select()/poll()/etc.
+ *
+ * @param daemon daemon to close down
+ */
+void
+MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
+{
+ struct MHD_Connection *pos;
+ const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
+ daemon->threading_mode);
+#ifdef UPGRADE_SUPPORT
+ const bool upg_allowed = (! daemon->disallow_upgrade);
+#endif /* UPGRADE_SUPPORT */
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ struct MHD_UpgradeResponseHandle *urh;
+ struct MHD_UpgradeResponseHandle *urhn;
+ const bool used_tls = (NULL != daemon->tls_api);
+
+ mhd_assert (NULL == daemon->worker_pool);
+ mhd_assert (daemon->shutdown);
+ /* give upgraded HTTPS connections a chance to finish */
+ /* 'daemon->urh_head' is not used in thread-per-connection mode. */
+ for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
+ {
+ urhn = urh->prev;
+ /* call generic forwarding function for passing data
+ with chance to detect that application is done. */
+ MHD_upgrade_response_handle_process_ (urh);
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* Resuming will move connection to cleanup list. */
+ MHD_request_resume (&urh->connection->request);
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+ /* Give suspended connections a chance to resume to avoid
+ running into the check for there not being any suspended
+ connections left in case of a tight race with a recently
+ resumed connection. */
+ if (! daemon->disallow_suspend_resume)
+ {
+ daemon->resuming = true; /* Force check for pending resume. */
+ MHD_resume_suspended_connections_ (daemon);
+ }
+ /* first, make sure all threads are aware of shutdown; need to
+ traverse DLLs in peace... */
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#ifdef UPGRADE_SUPPORT
+ if (upg_allowed)
+ {
+ struct MHD_Connection *susp;
+
+ susp = daemon->suspended_connections_tail;
+ while (NULL != susp)
+ {
+ if (NULL == susp->request.urh) /* "Upgraded" connection? */
+ MHD_PANIC (_ (
+ "MHD_stop_daemon() called while we have suspended connections.\n"));
+#ifdef HTTPS_SUPPORT
+ else if (used_tls &&
+ used_thr_p_c &&
+ (! susp->request.urh->clean_ready) )
+ shutdown (susp->request.urh->app.socket,
+ SHUT_RDWR); /* Wake thread by shutdown of app socket. */
+#endif /* HTTPS_SUPPORT */
+ else
+ {
+#ifdef HAVE_MESSAGES
+ if (! susp->request.urh->was_closed)
+ MHD_DLOG (daemon,
+ MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION,
+ _ (
+ "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
+#endif
+ susp->request.urh->was_closed = true;
+ /* If thread-per-connection is used, connection's thread
+ * may still processing "upgrade" (exiting). */
+ if (! used_thr_p_c)
+ MHD_connection_finish_forward_ (susp);
+ /* Do not use MHD_resume_connection() as mutex is
+ * already locked. */
+ susp->resuming = true;
+ daemon->resuming = true;
+ }
+ susp = susp->prev;
+ }
+ }
+ else /* This 'else' is combined with next 'if' */
+#endif /* UPGRADE_SUPPORT */
+ if (NULL != daemon->suspended_connections_head)
+ MHD_PANIC (_ (
+ "MHD_stop_daemon() called while we have suspended connections.\n"));
+ for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
+ {
+ shutdown (pos->socket_fd,
+ SHUT_RDWR);
+#if MHD_WINSOCK_SOCKETS
+ if ( (used_thr_p_c) &&
+ (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc,
+ "e")) )
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
+#endif
+ }
+
+ /* now, collect per-connection threads */
+ if (used_thr_p_c)
+ {
+ pos = daemon->connections_tail;
+ while (NULL != pos)
+ {
+ if (! pos->thread_joined)
+ {
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if (! MHD_join_thread_ (pos->pid.handle))
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ pos->thread_joined = true;
+ /* The thread may have concurrently modified the DLL,
+ need to restart from the beginning */
+ pos = daemon->connections_tail;
+ continue;
+ }
+ pos = pos->prev;
+ }
+ }
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+
+#ifdef UPGRADE_SUPPORT
+ /* Finished threads with "upgraded" connections need to be moved
+ * to cleanup list by resume_suspended_connections(). */
+ /* "Upgraded" connections that were not closed explicitly by
+ * application should be moved to cleanup list too. */
+ if (upg_allowed)
+ {
+ daemon->resuming = true; /* Force check for pending resume. */
+ MHD_resume_suspended_connections_ (daemon);
+ }
+#endif /* UPGRADE_SUPPORT */
+
+ /* now that we're alone, move everyone to cleanup */
+ while (NULL != (pos = daemon->connections_tail))
+ {
+ if ( (used_thr_p_c) &&
+ (! pos->thread_joined) )
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ close_connection (pos);
+ }
+ MHD_connection_cleanup_ (daemon);
+}
+
+
+/* end of daemon_close_all_connections.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_close_all_connections.h
^
|
@@ -0,0 +1,42 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_close_all_connections.h
+ * @brief function to close all connections open at a daemon
+ * @author Christian Grothoff
+ */
+#ifndef DAEMON_CLOSE_ALL_CONNECTIONS_H
+#define DAEMON_CLOSE_ALL_CONNECTIONS_H
+
+
+/**
+ * Close all connections for the daemon. Must only be called when
+ * MHD_Daemon::shutdown was set to true.
+ *
+ * @remark To be called only from thread that process daemon's
+ * select()/poll()/etc.
+ *
+ * @param daemon daemon to close down
+ */
+void
+MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_create.c
^
|
@@ -0,0 +1,138 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_create.c
+ * @brief main functions to create a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "init.h"
+
+
+/**
+ * Logging implementation that logs to a file given
+ * as the @a cls.
+ *
+ * @param cls a `FILE *` to log to
+ * @param sc status code of the event (ignored)
+ * @param fm format string (`printf()`-style)
+ * @param ap arguments to @a fm
+ * @ingroup logging
+ */
+static void
+file_logger (void *cls,
+ enum MHD_StatusCode sc,
+ const char *fm,
+ va_list ap)
+{
+ FILE *f = cls;
+
+ (void) sc;
+ (void) vfprintf (f,
+ fm,
+ ap);
+}
+
+
+/**
+ * Process escape sequences ('%HH') Updates val in place; the
+ * result should be UTF-8 encoded and cannot be larger than the input.
+ * The result must also still be 0-terminated.
+ *
+ * @param cls closure (use NULL)
+ * @param req handle to request, not used
+ * @param val value to unescape (modified in the process)
+ * @return length of the resulting val (strlen(val) maybe
+ * shorter afterwards due to elimination of escape sequences)
+ */
+static size_t
+unescape_wrapper (void *cls,
+ struct MHD_Request *req,
+ char *val)
+{
+ (void) cls; /* Mute compiler warning. */
+ (void) req; /* Mute compiler warning. */
+ return MHD_http_unescape (val);
+}
+
+
+/**
+ * Create (but do not yet start) an MHD daemon.
+ * Usually, you will want to set various options before
+ * starting the daemon with #MHD_daemon_start().
+ *
+ * @param cb function to be called for incoming requests
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
+ */
+struct MHD_Daemon *
+MHD_daemon_create (MHD_RequestCallback cb,
+ void *cb_cls)
+{
+ struct MHD_Daemon *daemon;
+
+ MHD_check_global_init_ ();
+ if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
+ return NULL;
+ memset (daemon,
+ 0,
+ sizeof (struct MHD_Daemon));
+#ifdef EPOLL_SUPPORT
+ daemon->epoll_itc_marker = "itc_marker";
+#endif
+ daemon->rc = cb;
+ daemon->rc_cls = cb_cls;
+ daemon->logger = &file_logger;
+ daemon->logger_cls = stderr;
+ daemon->unescape_cb = &unescape_wrapper;
+ daemon->connection_memory_limit_b = POOL_SIZE_DEFAULT;
+ daemon->connection_memory_increment_b = BUF_INC_SIZE_DEFAULT;
+#if ENABLE_DAUTH
+ daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT;
+#endif
+ daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT;
+ daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT;
+ daemon->listen_socket = MHD_INVALID_SOCKET;
+
+ if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
+ {
+ free (daemon);
+ return NULL;
+ }
+ if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
+ {
+ (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
+ free (daemon);
+ return NULL;
+ }
+#ifdef DAUTH_SUPPORT
+ if (! MHD_mutex_init_ (&daemon->nnc_lock))
+ {
+ (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
+ (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
+ free (daemon);
+ return NULL;
+ }
+#endif
+ return daemon;
+}
+
+
+/* end of daemon_create.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_destroy.c
^
|
@@ -0,0 +1,203 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_destroy.c
+ * @brief main functions to destroy a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "request_resume.h"
+#include "daemon_close_all_connections.h"
+
+
+/**
+ * Stop all worker threads from the worker pool.
+ *
+ * @param daemon master daemon controlling the workers
+ */
+static void
+stop_workers (struct MHD_Daemon *daemon)
+{
+ MHD_socket fd;
+ unsigned int i;
+
+ mhd_assert (1 < daemon->worker_pool_size);
+ mhd_assert (1 < daemon->threading_mode);
+ if (daemon->was_quiesced)
+ fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
+ else
+ fd = daemon->listen_socket;
+ /* Let workers shutdown in parallel. */
+ for (i = 0; i < daemon->worker_pool_size; i++)
+ {
+ daemon->worker_pool[i].shutdown = true;
+ if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
+ {
+ if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
+ "e"))
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
+ }
+ else
+ {
+ /* Better hope shutdown() works... */
+ mhd_assert (MHD_INVALID_SOCKET != fd);
+ }
+ }
+#ifdef HAVE_LISTEN_SHUTDOWN
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ (void) shutdown (fd,
+ SHUT_RDWR);
+ }
+#endif /* HAVE_LISTEN_SHUTDOWN */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
+ {
+ MHD_daemon_destroy (&daemon->worker_pool[i]);
+ }
+ free (daemon->worker_pool);
+ daemon->worker_pool = NULL;
+ /* FIXME: does this still hold? */
+ mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc));
+#ifdef EPOLL_SUPPORT
+ mhd_assert (-1 == daemon->epoll_fd);
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ mhd_assert (-1 == daemon->epoll_upgrade_fd);
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+}
+
+
+/**
+ * Shutdown and destroy an HTTP daemon.
+ *
+ * @param daemon daemon to stop
+ * @ingroup event
+ */
+void
+MHD_daemon_destroy (struct MHD_Daemon *daemon)
+{
+ MHD_socket fd;
+
+ daemon->shutdown = true;
+ if (daemon->was_quiesced)
+ fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
+ else
+ fd = daemon->listen_socket;
+
+ /* FIXME: convert from here to microhttpd2-style API! */
+
+ if (NULL != daemon->worker_pool)
+ { /* Master daemon with worker pool. */
+ stop_workers (daemon);
+ }
+ else
+ {
+ mhd_assert (0 == daemon->worker_pool_size);
+ /* Worker daemon or single-thread daemon. */
+ if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
+ {
+ /* Worker daemon or single daemon with internal thread(s). */
+ /* Separate thread(s) is used for polling sockets. */
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ if (! MHD_itc_activate_ (daemon->itc,
+ "e"))
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
+ }
+ else
+ {
+#ifdef HAVE_LISTEN_SHUTDOWN
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ if (NULL == daemon->master)
+ (void) shutdown (fd,
+ SHUT_RDWR);
+ }
+ else
+#endif /* HAVE_LISTEN_SHUTDOWN */
+ mhd_assert (false); /* Should never happen */
+ }
+
+ if (! MHD_join_thread_ (daemon->pid.handle))
+ {
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ }
+ /* close_all_connections() was called in daemon thread. */
+ }
+ else
+ {
+ /* No internal threads are used for polling sockets
+ (external event loop) */
+ MHD_daemon_close_all_connections_ (daemon);
+ }
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ MHD_itc_destroy_chk_ (daemon->itc);
+
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (-1 != daemon->epoll_fd) )
+ MHD_socket_close_chk_ (daemon->epoll_fd);
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (-1 != daemon->epoll_upgrade_fd) )
+ MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
+ }
+
+ if (NULL != daemon->master)
+ return;
+ /* Cleanup that should be done only one time in master/single daemon.
+ * Do not perform this cleanup in worker daemons. */
+
+ if (MHD_INVALID_SOCKET != fd)
+ MHD_socket_close_chk_ (fd);
+
+ /* TLS clean up */
+#ifdef HTTPS_SUPPORT
+ if (NULL != daemon->tls_api)
+ {
+#if FIXME_TLS_API
+ if (daemon->have_dhparams)
+ {
+ gnutls_dh_params_deinit (daemon->https_mem_dhparams);
+ daemon->have_dhparams = false;
+ }
+ gnutls_priority_deinit (daemon->priority_cache);
+ if (daemon->x509_cred)
+ gnutls_certificate_free_credentials (daemon->x509_cred);
+#endif
+ }
+#endif /* HTTPS_SUPPORT */
+
+#ifdef DAUTH_SUPPORT
+ free (daemon->nnc);
+ MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
+#endif
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+ free (daemon);
+}
+
+
+/* end of daemon_destroy.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_epoll.c
^
|
@@ -0,0 +1,517 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_epoll.c
+ * @brief functions to run epoll()-based event loop
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_add.h"
+#include "connection_call_handlers.h"
+#include "connection_finish_forward.h"
+#include "daemon_epoll.h"
+#include "upgrade_process.h"
+#include "request_resume.h"
+
+#ifdef EPOLL_SUPPORT
+
+/**
+ * How many events to we process at most per epoll() call? Trade-off
+ * between required stack-size and number of system calls we have to
+ * make; 128 should be way enough to avoid more than one system call
+ * for most scenarios, and still be moderate in stack size
+ * consumption. Embedded systems might want to choose a smaller value
+ * --- but why use epoll() on such a system in the first place?
+ */
+#define MAX_EVENTS 128
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+
+/**
+ * Checks whether @a urh has some data to process.
+ *
+ * @param urh upgrade handler to analyse
+ * @return 'true' if @a urh has some data to process,
+ * 'false' otherwise
+ */
+static bool
+is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
+{
+ const struct MHD_Connection *const connection = urh->connection;
+
+ if ( (0 == urh->in_buffer_size) &&
+ (0 == urh->out_buffer_size) &&
+ (0 == urh->in_buffer_used) &&
+ (0 == urh->out_buffer_used) )
+ return false;
+
+ if (connection->daemon->shutdown)
+ return true;
+
+ if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
+ (connection->tls_read_ready) ) &&
+ (urh->in_buffer_used < urh->in_buffer_size) )
+ return true;
+
+ if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
+ (urh->out_buffer_used < urh->out_buffer_size) )
+ return true;
+
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
+ (urh->out_buffer_used > 0) )
+ return true;
+
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
+ (urh->in_buffer_used > 0) )
+ return true;
+
+ return false;
+}
+
+
+/**
+ * Do epoll()-based processing for TLS connections that have been
+ * upgraded. This requires a separate epoll() invocation as we
+ * cannot use the `struct MHD_Connection` data structures for
+ * the `union epoll_data` in this case.
+ * @remark To be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon the daemmon for which we process connections
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+run_epoll_for_upgrade (struct MHD_Daemon *daemon)
+{
+ struct epoll_event events[MAX_EVENTS];
+ int num_events;
+ struct MHD_UpgradeResponseHandle *pos;
+ struct MHD_UpgradeResponseHandle *prev;
+
+ num_events = MAX_EVENTS;
+ while (MAX_EVENTS == num_events)
+ {
+ unsigned int i;
+
+ /* update event masks */
+ num_events = epoll_wait (daemon->epoll_upgrade_fd,
+ events,
+ MAX_EVENTS,
+ 0);
+ if (-1 == num_events)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_SC_OK;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
+ _ ("Call to epoll_wait failed: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
+ }
+ for (i = 0; i < (unsigned int) num_events; i++)
+ {
+ struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
+ struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
+ bool new_err_state = false;
+
+ if (urh->clean_ready)
+ continue;
+
+ /* Update ueh state based on what is ready according to epoll() */
+ if (0 != (events[i].events & EPOLLIN))
+ ueh->celi |= MHD_EPOLL_STATE_READ_READY;
+ if (0 != (events[i].events & EPOLLOUT))
+ ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (0 != (events[i].events & EPOLLHUP))
+ ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
+
+ if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
+ (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
+ {
+ /* Process new error state only one time
+ * and avoid continuously marking this connection
+ * as 'ready'. */
+ ueh->celi |= MHD_EPOLL_STATE_ERROR;
+ new_err_state = true;
+ }
+
+ if (! urh->in_eready_list)
+ {
+ if (new_err_state ||
+ is_urh_ready (urh))
+ {
+ EDLL_insert (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ urh);
+ urh->in_eready_list = true;
+ }
+ }
+ }
+ }
+ prev = daemon->eready_urh_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prevE;
+ MHD_upgrade_response_handle_process_ (pos);
+ if (! is_urh_ready (pos))
+ {
+ EDLL_remove (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ pos);
+ pos->in_eready_list = false;
+ }
+ /* Finished forwarding? */
+ if ( (0 == pos->in_buffer_size) &&
+ (0 == pos->out_buffer_size) &&
+ (0 == pos->in_buffer_used) &&
+ (0 == pos->out_buffer_used) )
+ {
+ MHD_connection_finish_forward_ (pos->connection);
+ pos->clean_ready = true;
+ /* If 'pos->was_closed' already was set to true, connection
+ * will be moved immediately to cleanup list. Otherwise
+ * connection will stay in suspended list until 'pos' will
+ * be marked with 'was_closed' by application. */
+ MHD_request_resume (&pos->connection->request);
+ }
+ }
+
+ return MHD_SC_OK;
+}
+
+
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+
+/**
+ * Do epoll()-based processing (this function is allowed to
+ * block if @a may_block is set to #MHD_YES).
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block true if blocking, false if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
+ bool may_block)
+{
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ static const char *const upgrade_marker = "upgrade_ptr";
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ struct MHD_Connection *pos;
+ struct MHD_Connection *prev;
+ struct epoll_event events[MAX_EVENTS];
+ struct epoll_event event;
+ int timeout_ms;
+ MHD_UNSIGNED_LONG_LONG timeout_ll;
+ int num_events;
+ unsigned int i;
+ MHD_socket ls;
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ bool run_upgraded = false;
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+ if (-1 == daemon->epoll_fd)
+ return MHD_SC_EPOLL_FD_INVALID; /* we're down! */
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) &&
+ (daemon->connections < daemon->global_connection_limit) &&
+ (! daemon->listen_socket_in_epoll) &&
+ (! daemon->at_limit) )
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = daemon;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ ls,
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_EPOLL_CTL_ADD_FAILED;
+ }
+ daemon->listen_socket_in_epoll = true;
+ }
+ if ( (daemon->was_quiesced) &&
+ (daemon->listen_socket_in_epoll) )
+ {
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ls,
+ NULL))
+ MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
+ daemon->listen_socket_in_epoll = false;
+ }
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if ( (! daemon->upgrade_fd_in_epoll) &&
+ (-1 != daemon->epoll_upgrade_fd) )
+ {
+ event.events = EPOLLIN | EPOLLOUT;
+ event.data.ptr = (void *) upgrade_marker;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ daemon->epoll_upgrade_fd,
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_EPOLL_CTL_ADD_FAILED;
+ }
+ daemon->upgrade_fd_in_epoll = true;
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ if ( (daemon->listen_socket_in_epoll) &&
+ ( (daemon->connections == daemon->global_connection_limit) ||
+ (daemon->at_limit) ||
+ (daemon->was_quiesced) ) )
+ {
+ /* we're at the connection limit, disable listen socket
+ for event loop for now */
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ls,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
+ daemon->listen_socket_in_epoll = false;
+ }
+
+ if ( (! daemon->disallow_suspend_resume) &&
+ (MHD_resume_suspended_connections_ (daemon)) )
+ may_block = false;
+
+ if (may_block)
+ {
+ if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */
+ MHD_daemon_get_timeout (daemon,
+ &timeout_ll))
+ {
+ if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
+ timeout_ms = INT_MAX;
+ else
+ timeout_ms = (int) timeout_ll;
+ }
+ else
+ timeout_ms = -1;
+ }
+ else
+ timeout_ms = 0;
+
+ /* Reset. New value will be set when connections are processed. */
+ /* Note: Used mostly for uniformity here as same situation is
+ * signaled in epoll mode by non-empty eready DLL. */
+ daemon->data_already_pending = false;
+
+ /* drain 'epoll' event queue; need to iterate as we get at most
+ MAX_EVENTS in one system call here; in practice this should
+ pretty much mean only one round, but better an extra loop here
+ than unfair behavior... */
+ num_events = MAX_EVENTS;
+ while (MAX_EVENTS == num_events)
+ {
+ /* update event masks */
+ num_events = epoll_wait (daemon->epoll_fd,
+ events,
+ MAX_EVENTS,
+ timeout_ms);
+ if (-1 == num_events)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_SC_OK;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
+ _ ("Call to epoll_wait failed: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
+ }
+ for (i = 0; i<(unsigned int) num_events; i++)
+ {
+ /* First, check for the values of `ptr` that would indicate
+ that this event is not about a normal connection. */
+ if (NULL == events[i].data.ptr)
+ continue; /* shutdown signal! */
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if (upgrade_marker == events[i].data.ptr)
+ {
+ /* activity on an upgraded connection, we process
+ those in a separate epoll() */
+ run_upgraded = true;
+ continue;
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ if (daemon->epoll_itc_marker == events[i].data.ptr)
+ {
+ /* It's OK to clear ITC here as all external
+ conditions will be processed later. */
+ MHD_itc_clear_ (daemon->itc);
+ continue;
+ }
+ if (daemon == events[i].data.ptr)
+ {
+ /* Check for error conditions on listen socket. */
+ /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
+ if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
+ {
+ unsigned int series_length = 0;
+ /* Run 'accept' until it fails or daemon at limit of connections.
+ * Do not accept more then 10 connections at once. The rest will
+ * be accepted on next turn (level trigger is used for listen
+ * socket). */
+ while ( (MHD_SC_OK ==
+ MHD_accept_connection_ (daemon)) &&
+ (series_length < 10) &&
+ (daemon->connections < daemon->global_connection_limit) &&
+ (! daemon->at_limit) )
+ series_length++;
+ }
+ continue;
+ }
+ /* this is an event relating to a 'normal' connection,
+ remember the event and if appropriate mark the
+ connection as 'eready'. */
+ pos = events[i].data.ptr;
+ /* normal processing: update read/write data */
+ if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
+ if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ else
+ {
+ if (0 != (events[i].events & EPOLLIN))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
+ if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) ||
+ (pos->request.read_buffer_size >
+ pos->request.read_buffer_offset) ) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ if (0 != (events[i].events & EPOLLOUT))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
+ if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ }
+ }
+ }
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if (run_upgraded)
+ run_epoll_for_upgrade (daemon); /* FIXME: return value? */
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+ /* process events for connections */
+ prev = daemon->eready_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prevE;
+ MHD_connection_call_handlers_ (pos,
+ 0 != (pos->epoll_state
+ & MHD_EPOLL_STATE_READ_READY),
+ 0 != (pos->epoll_state
+ & MHD_EPOLL_STATE_WRITE_READY),
+ 0 != (pos->epoll_state
+ & MHD_EPOLL_STATE_ERROR));
+ if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
+ (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
+ | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
+ {
+ if ( ((MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
+ ((MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
+ (MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) )
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ }
+
+ /* Finally, handle timed-out connections; we need to do this here
+ as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything,
+ as the other event loops do. As timeouts do not get an explicit
+ event, we need to find those connections that might have timed out
+ here.
+
+ Connections with custom timeouts must all be looked at, as we
+ do not bother to sort that (presumably very short) list. */prev = daemon->manual_timeout_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prevX;
+ MHD_request_handle_idle_ (&pos->request);
+ }
+ /* Connections with the default timeout are sorted by prepending
+ them to the head of the list whenever we touch the connection;
+ thus it suffices to iterate from the tail until the first
+ connection is NOT timed out */
+ prev = daemon->normal_timeout_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prevX;
+ MHD_request_handle_idle_ (&pos->request);
+ if (MHD_REQUEST_CLOSED != pos->request.state)
+ break; /* sorted by timeout, no need to visit the rest! */
+ }
+ return MHD_SC_OK;
+}
+
+
+#endif
+
+/* end of daemon_epoll.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_epoll.h
^
|
@@ -0,0 +1,46 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_epoll.h
+ * @brief non-public functions provided by daemon_epoll.c
+ * @author Christian Grothoff
+ */
+
+#ifndef DAEMON_EPOLL_H
+#define DAEMON_EPOLL_H
+
+#ifdef EPOLL_SUPPORT
+
+/**
+ * Do epoll()-based processing (this function is allowed to
+ * block if @a may_block is set to #MHD_YES).
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block true if blocking, false if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
+ bool may_block)
+MHD_NONNULL (1);
+
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_get_timeout.c
^
|
@@ -0,0 +1,127 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_get_timeout.c
+ * @brief function to obtain timeout for event loop
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Obtain timeout value for polling function for this daemon.
+ * This function set value to amount of milliseconds for which polling
+ * function (`select()` or `poll()`) should at most block, not the
+ * timeout value set for connections.
+ * It is important to always use this function, even if connection
+ * timeout is not set, as in some cases MHD may already have more
+ * data to process on next turn (data pending in TLS buffers,
+ * connections are already ready with epoll etc.) and returned timeout
+ * will be zero.
+ *
+ * @param daemon daemon to query for timeout
+ * @param timeout set to the timeout (in milliseconds)
+ * @return #MHD_SC_OK on success, #MHD_SC_NO_TIMEOUT if timeouts are
+ * not used (or no connections exist that would
+ * necessitate the use of a timeout right now), otherwise
+ * an error code
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
+ MHD_UNSIGNED_LONG_LONG *timeout)
+{
+ time_t earliest_deadline;
+ time_t now;
+ struct MHD_Connection *pos;
+ bool have_timeout;
+
+ if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT,
+ _ ("Illegal call to MHD_get_timeout.\n"));
+#endif
+ return MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT;
+ }
+
+ if (daemon->data_already_pending)
+ {
+ /* Some data already waiting to be processed. */
+ *timeout = 0;
+ return MHD_SC_OK;
+ }
+
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ ((NULL != daemon->eready_head)
+#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
+ || (NULL != daemon->eready_urh_head)
+#endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
+ ) )
+ {
+ /* Some connection(s) already have some data pending. */
+ *timeout = 0;
+ return MHD_SC_OK;
+ }
+#endif /* EPOLL_SUPPORT */
+
+ have_timeout = false;
+ earliest_deadline = 0; /* avoid compiler warnings */
+ for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
+ {
+ if (0 != pos->connection_timeout)
+ {
+ if ( (! have_timeout) ||
+ (earliest_deadline - pos->last_activity > pos->connection_timeout) )
+ earliest_deadline = pos->last_activity + pos->connection_timeout;
+ have_timeout = true;
+ }
+ }
+ /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
+ pos = daemon->normal_timeout_tail;
+ if ( (NULL != pos) &&
+ (0 != pos->connection_timeout) )
+ {
+ if ( (! have_timeout) ||
+ (earliest_deadline - pos->connection_timeout > pos->last_activity) )
+ earliest_deadline = pos->last_activity + pos->connection_timeout;
+ have_timeout = true;
+ }
+
+ if (! have_timeout)
+ return MHD_SC_NO_TIMEOUT;
+ now = MHD_monotonic_sec_counter ();
+ if (earliest_deadline < now)
+ *timeout = 0;
+ else
+ {
+ const time_t second_left = earliest_deadline - now;
+ if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */
+ *timeout = ULLONG_MAX;
+ else
+ *timeout = 1000LL * second_left;
+ }
+ return MHD_SC_OK;
+}
+
+
+/* end of daemon_get_timeout.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_info.c
^
|
@@ -0,0 +1,106 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_info.c
+ * @brief implementation of MHD_daemon_get_information_sz()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_cleanup.h"
+
+
+/**
+ * Obtain information about the given daemon.
+ * Use wrapper macro #MHD_daemon_get_information() instead of direct use
+ * of this function.
+ *
+ * @param daemon what daemon to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_DaemonInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+enum MHD_Bool
+MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
+ enum MHD_DaemonInformationType info_type,
+ union MHD_DaemonInformation *return_value,
+ size_t return_value_size)
+{
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
+ switch (info_type)
+ {
+ case MHD_DAEMON_INFORMATION_LISTEN_SOCKET:
+ CHECK_SIZE (MHD_socket);
+ return_value->listen_socket
+ = daemon->listen_socket;
+ return MHD_YES;
+#ifdef EPOLL_SUPPORT
+ case MHD_DAEMON_INFORMATION_EPOLL_FD:
+ CHECK_SIZE (int);
+ // FIXME: maybe return MHD_NO if we are not using EPOLL?
+ return_value->epoll_fd = daemon->epoll_fd;
+ return MHD_YES;
+#endif
+ case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS:
+ CHECK_SIZE (unsigned int);
+ if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode)
+ {
+ /* Assumes that MHD_run() in not called in other thread
+ (of the application) at the same time. */
+ MHD_connection_cleanup_ (daemon);
+ return_value->num_connections
+ = daemon->connections;
+ }
+ else if (daemon->worker_pool)
+ {
+ unsigned int i;
+ /* Collect the connection information stored in the workers. */
+ return_value->num_connections = 0;
+ for (i = 0; i < daemon->worker_pool_size; i++)
+ {
+ /* FIXME: next line is thread-safe only if read is atomic. */
+ return_value->num_connections
+ += daemon->worker_pool[i].connections;
+ }
+ }
+ else
+ return_value->num_connections
+ = daemon->connections;
+ return MHD_YES;
+ case MHD_DAEMON_INFORMATION_BIND_PORT:
+ CHECK_SIZE (uint16_t);
+ // FIXME: return MHD_NO if port is not known/UNIX?
+ return_value->port = daemon->listen_port;
+ return MHD_YES;
+ default:
+ return MHD_NO;
+ }
+
+#undef CHECK_SIZE
+}
+
+
+/* end of daemon_info.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_ip_limit.c
^
|
@@ -0,0 +1,303 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_ip_limit.c
+ * @brief counting of connections per IP
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "daemon_ip_limit.h"
+#if HAVE_SEARCH_H
+#include <search.h>
+#else
+#include "tsearch.h"
+#endif
+
+
+/**
+ * Maintain connection count for single address.
+ */
+struct MHD_IPCount
+{
+ /**
+ * Address family. AF_INET or AF_INET6 for now.
+ */
+ int family;
+
+ /**
+ * Actual address.
+ */
+ union
+ {
+ /**
+ * IPv4 address.
+ */
+ struct in_addr ipv4;
+#if HAVE_INET6
+ /**
+ * IPv6 address.
+ */
+ struct in6_addr ipv6;
+#endif
+ } addr;
+
+ /**
+ * Counter.
+ */
+ unsigned int count;
+};
+
+
+/**
+ * Trace up to and return master daemon. If the supplied daemon
+ * is a master, then return the daemon itself.
+ *
+ * @param daemon handle to a daemon
+ * @return master daemon handle
+ */
+static struct MHD_Daemon*
+get_master (struct MHD_Daemon *daemon)
+{
+ while (NULL != daemon->master)
+ daemon = daemon->master;
+ return daemon;
+}
+
+
+/**
+ * Lock shared structure for IP connection counts and connection DLLs.
+ *
+ * @param daemon handle to daemon where lock is
+ */
+static void
+MHD_ip_count_lock (struct MHD_Daemon *daemon)
+{
+ MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex);
+}
+
+
+/**
+ * Unlock shared structure for IP connection counts and connection DLLs.
+ *
+ * @param daemon handle to daemon where lock is
+ */
+static void
+MHD_ip_count_unlock (struct MHD_Daemon *daemon)
+{
+ MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex);
+}
+
+
+/**
+ * Tree comparison function for IP addresses (supplied to tsearch() family).
+ * We compare everything in the struct up through the beginning of the
+ * 'count' field.
+ *
+ * @param a1 first address to compare
+ * @param a2 second address to compare
+ * @return -1, 0 or 1 depending on result of compare
+ */
+static int
+MHD_ip_addr_compare (const void *a1,
+ const void *a2)
+{
+ return memcmp (a1,
+ a2,
+ offsetof (struct MHD_IPCount,
+ count));
+}
+
+
+/**
+ * Parse address and initialize @a key using the address.
+ *
+ * @param addr address to parse
+ * @param addrlen number of bytes in @a addr
+ * @param key where to store the parsed address
+ * @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type)
+ */
+static int
+MHD_ip_addr_to_key (const struct sockaddr *addr,
+ socklen_t addrlen,
+ struct MHD_IPCount *key)
+{
+ memset (key,
+ 0,
+ sizeof(*key));
+
+ /* IPv4 addresses */
+ if (sizeof (struct sockaddr_in) == addrlen)
+ {
+ const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
+
+ key->family = AF_INET;
+ memcpy (&key->addr.ipv4,
+ &addr4->sin_addr,
+ sizeof(addr4->sin_addr));
+ return MHD_YES;
+ }
+
+#if HAVE_INET6
+ /* IPv6 addresses */
+ if (sizeof (struct sockaddr_in6) == addrlen)
+ {
+ const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
+
+ key->family = AF_INET6;
+ memcpy (&key->addr.ipv6,
+ &addr6->sin6_addr,
+ sizeof(addr6->sin6_addr));
+ return MHD_YES;
+ }
+#endif
+
+ /* Some other address */
+ return MHD_NO;
+}
+
+
+/**
+ * Check if IP address is over its limit in terms of the number
+ * of allowed concurrent connections. If the IP is still allowed,
+ * increments the connection counter.
+ *
+ * @param daemon handle to daemon where connection counts are tracked
+ * @param addr address to add (or increment counter)
+ * @param addrlen number of bytes in @a addr
+ * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit.
+ * Also returns #MHD_NO if fails to allocate memory.
+ */
+int
+MHD_ip_limit_add (struct MHD_Daemon *daemon,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ struct MHD_IPCount *key;
+ void **nodep;
+ void *node;
+ int result;
+
+ daemon = get_master (daemon);
+ /* Ignore if no connection limit assigned */
+ if (0 == daemon->ip_connection_limit)
+ return MHD_YES;
+
+ if (NULL == (key = malloc (sizeof(*key))))
+ return MHD_NO;
+
+ /* Initialize key */
+ if (MHD_NO == MHD_ip_addr_to_key (addr,
+ addrlen,
+ key))
+ {
+ /* Allow unhandled address types through */
+ free (key);
+ return MHD_YES;
+ }
+ MHD_ip_count_lock (daemon);
+
+ /* Search for the IP address */
+ if (NULL == (nodep = tsearch (key,
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_IP_COUNTER_FAILURE,
+ _ ("Failed to add IP connection count node.\n"));
+#endif
+ MHD_ip_count_unlock (daemon);
+ free (key);
+ return MHD_NO;
+ }
+ node = *nodep;
+ /* If we got an existing node back, free the one we created */
+ if (node != key)
+ free (key);
+ key = (struct MHD_IPCount *) node;
+ /* Test if there is room for another connection; if so,
+ * increment count */
+ result = (key->count < daemon->ip_connection_limit) ? MHD_YES : MHD_NO;
+ if (MHD_YES == result)
+ ++key->count;
+
+ MHD_ip_count_unlock (daemon);
+ return result;
+}
+
+
+/**
+ * Decrement connection count for IP address, removing from table
+ * count reaches 0.
+ *
+ * @param daemon handle to daemon where connection counts are tracked
+ * @param addr address to remove (or decrement counter)
+ * @param addrlen number of bytes in @a addr
+ */
+void
+MHD_ip_limit_del (struct MHD_Daemon *daemon,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ struct MHD_IPCount search_key;
+ struct MHD_IPCount *found_key;
+ void **nodep;
+
+ daemon = get_master (daemon);
+ /* Ignore if no connection limit assigned */
+ if (0 == daemon->ip_connection_limit)
+ return;
+ /* Initialize search key */
+ if (MHD_NO == MHD_ip_addr_to_key (addr,
+ addrlen,
+ &search_key))
+ return;
+
+ MHD_ip_count_lock (daemon);
+
+ /* Search for the IP address */
+ if (NULL == (nodep = tfind (&search_key,
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare)))
+ {
+ /* Something's wrong if we couldn't find an IP address
+ * that was previously added */
+ MHD_PANIC (_ ("Failed to find previously-added IP address.\n"));
+ }
+ found_key = (struct MHD_IPCount *) *nodep;
+ /* Validate existing count for IP address */
+ if (0 == found_key->count)
+ {
+ MHD_PANIC (_ ("Previously-added IP address had counter of zero.\n"));
+ }
+ /* Remove the node entirely if count reduces to 0 */
+ if (0 == --found_key->count)
+ {
+ tdelete (found_key,
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare);
+ free (found_key);
+ }
+
+ MHD_ip_count_unlock (daemon);
+}
+
+
+/* end of daemon_ip_limit.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_ip_limit.h
^
|
@@ -0,0 +1,60 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/daemon_ip_limit.h
+ * @brief counting of connections per IP
+ * @author Christian Grothoff
+ */
+
+#ifndef DAEMON_IP_LIMIT_H
+#define DAEMON_IP_LIMIT_H
+
+/**
+ * Check if IP address is over its limit in terms of the number
+ * of allowed concurrent connections. If the IP is still allowed,
+ * increments the connection counter.
+ *
+ * @param daemon handle to daemon where connection counts are tracked
+ * @param addr address to add (or increment counter)
+ * @param addrlen number of bytes in @a addr
+ * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit.
+ * Also returns #MHD_NO if fails to allocate memory.
+ */
+int
+MHD_ip_limit_add (struct MHD_Daemon *daemon,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+MHD_NONNULL (1,2);
+
+
+/**
+ * Decrement connection count for IP address, removing from table
+ * count reaches 0.
+ *
+ * @param daemon handle to daemon where connection counts are tracked
+ * @param addr address to remove (or decrement counter)
+ * @param addrlen number of bytes in @a addr
+ */
+void
+MHD_ip_limit_del (struct MHD_Daemon *daemon,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+MHD_NONNULL (1,2);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_options.c
^
|
@@ -0,0 +1,780 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_options.c
+ * @brief boring functions to manipulate daemon options
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+/**
+ * Set logging method. Specify NULL to disable logging entirely. By
+ * default (if this option is not given), we log error messages to
+ * stderr.
+ *
+ * @param daemon which instance to setup logging for
+ * @param logger function to invoke
+ * @param logger_cls closure for @a logger
+ */
+void
+MHD_daemon_set_logger (struct MHD_Daemon *daemon,
+ MHD_LoggingCallback logger,
+ void *logger_cls)
+{
+ daemon->logger = logger;
+ daemon->logger_cls = logger_cls;
+}
+
+
+/**
+ * Suppress use of "Date" header as this system has no RTC.
+ *
+ * @param daemon which instance to disable clock for.
+ */
+void
+MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon)
+{
+ daemon->suppress_date = true;
+}
+
+
+/**
+ * Disable use of inter-thread communication channel.
+ * #MHD_daemon_disable_itc() can be used with
+ * #MHD_daemon_thread_internal() to perform some additional
+ * optimizations (in particular, not creating a pipe for IPC
+ * signalling). If it is used, certain functions like
+ * #MHD_daemon_quiesce() or #MHD_connection_add() or
+ * #MHD_action_suspend() cannot be used anymore.
+ * #MHD_daemon_disable_itc() is not beneficial on platforms where
+ * select()/poll()/other signal shutdown() of a listen socket.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to disable itc for
+ */
+void
+MHD_daemon_disable_itc (struct MHD_Daemon *daemon)
+{
+ daemon->disable_itc = true;
+}
+
+
+/**
+ * Enable `turbo`. Disables certain calls to `shutdown()`,
+ * enables aggressive non-blocking optimistic reads and
+ * other potentially unsafe optimizations.
+ * Most effects only happen with #MHD_ELS_EPOLL.
+ *
+ * @param daemon which instance to enable turbo for
+ */
+void
+MHD_daemon_enable_turbo (struct MHD_Daemon *daemon)
+{
+ daemon->enable_turbo = true;
+}
+
+
+/**
+ * Disable #MHD_action_suspend() functionality.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to disable suspend for
+ */
+void
+MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
+{
+ daemon->disallow_suspend_resume = true;
+}
+
+
+/**
+ * You need to set this option if you want to disable use of HTTP "Upgrade".
+ * "Upgrade" may require usage of additional internal resources,
+ * which we can avoid providing if they will not be used.
+ *
+ * You should only use this function if you are sure you do
+ * satisfy all of its requirements and need a generally minor
+ * boost in performance.
+ *
+ * @param daemon which instance to enable suspend/resume for
+ */
+void
+MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
+{
+ daemon->disallow_upgrade = true;
+}
+
+
+/**
+ * Configure TCP_FASTOPEN option, including setting a
+ * custom @a queue_length.
+ *
+ * Note that having a larger queue size can cause resource exhaustion
+ * attack as the TCP stack has to now allocate resources for the SYN
+ * packet along with its DATA.
+ *
+ * @param daemon which instance to configure TCP_FASTOPEN for
+ * @param fom under which conditions should we use TCP_FASTOPEN?
+ * @param queue_length queue length to use, default is 50 if this
+ * option is never given.
+ * @return #MHD_YES upon success, #MHD_NO if #MHD_FOM_REQUIRE was
+ * given, but TCP_FASTOPEN is not available on the platform
+ */
+enum MHD_Bool
+MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
+ enum MHD_FastOpenMethod fom,
+ unsigned int queue_length)
+{
+ daemon->fast_open_method = fom;
+ daemon->fo_queue_length = queue_length;
+ switch (fom)
+ {
+ case MHD_FOM_DISABLE:
+ return MHD_YES;
+ case MHD_FOM_AUTO:
+ return MHD_YES;
+ case MHD_FOM_REQUIRE:
+#ifdef TCP_FASTOPEN
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ }
+ return MHD_NO;
+}
+
+
+/**
+ * Bind to the given TCP port and address family.
+ *
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ * Ineffective in conjunction with #MHD_daemon_bind_sa().
+ *
+ * If neither this option nor the other two mentioned above
+ * is specified, MHD will simply not listen on any socket!
+ *
+ * @param daemon which instance to configure the TCP port for
+ * @param af address family to use
+ * @param port port to use, 0 to bind to a random (free) port
+ */
+void
+MHD_daemon_bind_port (struct MHD_Daemon *daemon,
+ enum MHD_AddressFamily af,
+ uint16_t port)
+{
+ daemon->listen_af = af;
+ daemon->listen_port = port;
+}
+
+
+/**
+ * Bind to the given socket address.
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon which instance to configure the binding address for
+ * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6)
+ * or even a UNIX domain socket (AF_UNIX)
+ * @param sa_len number of bytes in @a sa
+ */
+void
+MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
+ const struct sockaddr *sa,
+ size_t sa_len)
+{
+ memcpy (&daemon->listen_sa,
+ sa,
+ sa_len);
+ daemon->listen_sa_len = sa_len;
+}
+
+
+/**
+ * Use the given backlog for the listen() call.
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon which instance to configure the backlog for
+ * @param listen_backlog backlog to use
+ */
+void
+MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
+ int listen_backlog)
+{
+ daemon->listen_backlog = listen_backlog;
+}
+
+
+/**
+ * If present true, allow reusing address:port socket (by using
+ * SO_REUSEPORT on most platform, or platform-specific ways). If
+ * present and set to false, disallow reusing address:port socket
+ * (does nothing on most platform, but uses SO_EXCLUSIVEADDRUSE on
+ * Windows).
+ * Ineffective in conjunction with #MHD_daemon_listen_socket().
+ *
+ * @param daemon daemon to configure address reuse for
+ */
+void
+MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon)
+{
+ daemon->allow_address_reuse = true;
+}
+
+
+/**
+ * Use SHOUTcast. This will cause the response to begin
+ * with the SHOUTcast "ICY" line instead of "HTTP".
+ *
+ * @param daemon daemon to set SHOUTcast option for
+ */
+_MHD_EXTERN void
+MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
+{
+ daemon->enable_shoutcast = true;
+}
+
+
+/**
+ * Accept connections from the given socket. Socket
+ * must be a TCP or UNIX domain (stream) socket.
+ *
+ * Unless -1 is given, this disables other listen options, including
+ * #MHD_daemon_bind_sa(), #MHD_daemon_bind_port(),
+ * #MHD_daemon_listen_queue() and
+ * #MHD_daemon_listen_allow_address_reuse().
+ *
+ * @param daemon daemon to set listen socket for
+ * @param listen_socket listen socket to use,
+ * MHD_INVALID_SOCKET value will cause this call to be
+ * ignored (other binding options may still be effective)
+ */
+void
+MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
+ MHD_socket listen_socket)
+{
+ daemon->listen_socket = listen_socket;
+}
+
+
+/**
+ * Force use of a particular event loop system call.
+ *
+ * @param daemon daemon to set event loop style for
+ * @param els event loop syscall to use
+ * @return #MHD_NO on failure, #MHD_YES on success
+ */
+enum MHD_Bool
+MHD_daemon_event_loop (struct MHD_Daemon *daemon,
+ enum MHD_EventLoopSyscall els)
+{
+ switch (els)
+ {
+ case MHD_ELS_AUTO:
+ break; /* should always be OK */
+ case MHD_ELS_SELECT:
+ break; /* should always be OK */
+ case MHD_ELS_POLL:
+#ifdef HAVE_POLL
+ break;
+#else
+ return MHD_NO; /* not supported */
+#endif
+ case MHD_ELS_EPOLL:
+#ifdef EPOLL_SUPPORT
+ break;
+#else
+ return MHD_NO; /* not supported */
+#endif
+ default:
+ return MHD_NO; /* not supported (presumably future ABI extension) */
+ }
+ daemon->event_loop_syscall = els;
+ return MHD_YES;
+}
+
+
+/**
+ * Set how strictly MHD will enforce the HTTP protocol.
+ *
+ * @param daemon daemon to configure strictness for
+ * @param sl how strict should we be
+ */
+void
+MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
+ enum MHD_ProtocolStrictLevel sl)
+{
+ daemon->protocol_strict_level = sl;
+}
+
+
+/**
+ * Enable and configure TLS.
+ *
+ * @param daemon which instance should be configured
+ * @param tls_backend which TLS backend should be used,
+ * currently only "gnutls" is supported. You can
+ * also specify NULL for best-available (which is the default).
+ * @param ciphers which ciphers should be used by TLS, default is
+ * "NORMAL"
+ * @return status code, #MHD_SC_OK upon success
+ * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown
+ * #MHD_TLS_DISABLED if this build of MHD does not support TLS
+ * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported
+ * by this backend
+ */
+enum MHD_StatusCode
+MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
+ const char *tls_backend,
+ const char *ciphers)
+{
+#if ! (defined(HTTPS_SUPPORT) && defined (HAVE_DLFCN_H))
+ return MHD_SC_TLS_DISABLED;
+#else
+ char filename[1024];
+ int res;
+ MHD_TLS_PluginInit init;
+
+ /* todo: .dll on W32? */
+ res = MHD_snprintf_ (filename,
+ sizeof (filename),
+ "%s/libmicrohttpd_tls_%s.so",
+ MHD_PLUGIN_INSTALL_PREFIX,
+ tls_backend);
+ if (0 >= res)
+ return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */
+ if (NULL ==
+ (daemon->tls_backend_lib = dlopen (filename,
+ RTLD_NOW | RTLD_LOCAL)))
+ return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */
+ if (NULL == (init = dlsym (daemon->tls_backend_lib,
+ "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
+
+ {
+ dlclose (daemon->tls_backend_lib);
+ daemon->tls_backend_lib = NULL;
+ return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
+ }
+ if (NULL == (daemon->tls_api = init (ciphers)))
+ {
+ dlclose (daemon->tls_backend_lib);
+ daemon->tls_backend_lib = NULL;
+ return MHD_SC_TLS_CIPHERS_INVALID; /* possibly wrong version installed */
+ }
+ return MHD_SC_OK;
+#endif
+}
+
+
+/**
+ * Provide TLS key and certificate data in-memory.
+ *
+ * @param daemon which instance should be configured
+ * @param mem_key private key (key.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param mem_cert certificate (cert.pem) to be used by the
+ * HTTPS daemon. Must be the actual data in-memory, not a filename.
+ * @param pass passphrase phrase to decrypt 'key.pem', NULL
+ * if @param mem_key is in cleartext already
+ * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
+ * if the TLS backend is not yet setup.
+ */
+enum MHD_StatusCode
+MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
+ const char *mem_key,
+ const char *mem_cert,
+ const char *pass)
+{
+#ifndef HTTPS_SUPPORT
+ return MHD_SC_TLS_DISABLED;
+#else
+ struct MHD_TLS_Plugin *plugin;
+
+ if (NULL == (plugin = daemon->tls_api))
+ return MHD_SC_TLS_BACKEND_UNINITIALIZED;
+ return plugin->init_kcp (plugin->cls,
+ mem_key,
+ mem_cert,
+ pass);
+#endif
+}
+
+
+/**
+ * Configure DH parameters (dh.pem) to use for the TLS key
+ * exchange.
+ *
+ * @param daemon daemon to configure tls for
+ * @param dh parameters to use
+ * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
+ * if the TLS backend is not yet setup.
+ */
+enum MHD_StatusCode
+MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
+ const char *dh)
+{
+#ifndef HTTPS_SUPPORT
+ return MHD_SC_TLS_DISABLED;
+#else
+ struct MHD_TLS_Plugin *plugin;
+
+ if (NULL == (plugin = daemon->tls_api))
+ return MHD_SC_TLS_BACKEND_UNINITIALIZED;
+ return plugin->init_dhparams (plugin->cls,
+ dh);
+#endif
+}
+
+
+/**
+ * Memory pointer for the certificate (ca.pem) to be used by the
+ * HTTPS daemon for client authentication.
+ *
+ * @param daemon daemon to configure tls for
+ * @param mem_trust memory pointer to the certificate
+ * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED
+ * if the TLS backend is not yet setup.
+ */
+enum MHD_StatusCode
+MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
+ const char *mem_trust)
+{
+#ifndef HTTPS_SUPPORT
+ return MHD_SC_TLS_DISABLED;
+#else
+ struct MHD_TLS_Plugin *plugin;
+
+ if (NULL == (plugin = daemon->tls_api))
+ return MHD_SC_TLS_BACKEND_UNINITIALIZED;
+ return plugin->init_mem_trust (plugin->cls,
+ mem_trust);
+#endif
+}
+
+
+/**
+ * Configure daemon credentials type for GnuTLS.
+ *
+ * @param gnutls_credentials must be a value of
+ * type `gnutls_credentials_type_t`
+ * @return #MHD_SC_OK upon success; TODO: define failure modes
+ */
+enum MHD_StatusCode
+MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
+ int gnutls_credentials)
+{
+#ifndef HTTPS_SUPPORT
+ return MHD_SC_TLS_DISABLED;
+#else
+ struct MHD_TLS_Plugin *plugin;
+
+ if (NULL == (plugin = daemon->tls_api))
+ return MHD_SC_TLS_BACKEND_UNINITIALIZED;
+ return MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED;
+#endif
+}
+
+
+/**
+ * Provide TLS key and certificate data via callback.
+ *
+ * Use a callback to determine which X.509 certificate should be used
+ * for a given HTTPS connection. This option provides an alternative
+ * to #MHD_daemon_tls_key_and_cert_from_memory(). You must use this
+ * version if multiple domains are to be hosted at the same IP address
+ * using TLS's Server Name Indication (SNI) extension. In this case,
+ * the callback is expected to select the correct certificate based on
+ * the SNI information provided. The callback is expected to access
+ * the SNI data using `gnutls_server_name_get()`. Using this option
+ * requires GnuTLS 3.0 or higher.
+ *
+ * @param daemon daemon to configure callback for
+ * @param cb must be of type `gnutls_certificate_retrieve_function2 *`.
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
+ void *cb)
+{
+#ifndef HTTPS_SUPPORT
+ return MHD_SC_TLS_DISABLED;
+#else
+ struct MHD_TLS_Plugin *plugin;
+
+ if (NULL == (plugin = daemon->tls_api))
+ return MHD_SC_TLS_BACKEND_UNINITIALIZED;
+ return MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED;
+#endif
+}
+
+
+/**
+ * Specify threading mode to use.
+ *
+ * @param daemon daemon to configure
+ * @param tm mode to use (positive values indicate the
+ * number of worker threads to be used)
+ */
+void
+MHD_daemon_threading_mode (struct MHD_Daemon *daemon,
+ enum MHD_ThreadingMode tm)
+{
+ daemon->threading_mode = tm;
+}
+
+
+/**
+ * Set a policy callback that accepts/rejects connections
+ * based on the client's IP address. This function will be called
+ * before a connection object is created.
+ *
+ * @param daemon daemon to set policy for
+ * @param apc function to call to check the policy
+ * @param apc_cls closure for @a apc
+ */
+void
+MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
+ MHD_AcceptPolicyCallback apc,
+ void *apc_cls)
+{
+ daemon->accept_policy_cb = apc;
+ daemon->accept_policy_cb_cls = apc_cls;
+}
+
+
+/**
+ * Register a callback to be called first for every request
+ * (before any parsing of the header). Makes it easy to
+ * log the full URL.
+ *
+ * @param daemon daemon for which to set the logger
+ * @param cb function to call
+ * @param cb_cls closure for @a cb
+ */
+void
+MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
+ MHD_EarlyUriLogCallback cb,
+ void *cb_cls)
+{
+ daemon->early_uri_logger_cb = cb;
+ daemon->early_uri_logger_cb_cls = cb_cls;
+}
+
+
+/**
+ * Register a function that should be called whenever a connection is
+ * started or closed.
+ *
+ * @param daemon daemon to set callback for
+ * @param ncc function to call to check the policy
+ * @param ncc_cls closure for @a apc
+ */
+void
+MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
+ MHD_NotifyConnectionCallback ncc,
+ void *ncc_cls)
+{
+ daemon->notify_connection_cb = ncc;
+ daemon->notify_connection_cb_cls = ncc_cls;
+}
+
+
+/**
+ * Maximum memory size per connection.
+ * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT).
+ * Values above 128k are unlikely to result in much benefit, as half
+ * of the memory will be typically used for IO, and TCP buffers are
+ * unlikely to support window sizes above 64k on most systems.
+ *
+ * @param daemon daemon to configure
+ * @param memory_limit_b connection memory limit to use in bytes
+ * @param memory_increment_b increment to use when growing the read buffer, must be smaller than @a memory_limit_b
+ */
+void
+MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
+ size_t memory_limit_b,
+ size_t memory_increment_b)
+{
+ if (memory_increment_b >= memory_limit_b)
+ MHD_PANIC ("Sane memory increment must be below memory limit.\n");
+ daemon->connection_memory_limit_b = memory_limit_b;
+ daemon->connection_memory_increment_b = memory_increment_b;
+}
+
+
+/**
+ * Desired size of the stack for threads created by MHD. Use 0 for
+ * system default. Only useful if the selected threading mode
+ * is not #MHD_TM_EXTERNAL_EVENT_LOOP.
+ *
+ * @param daemon daemon to configure
+ * @param stack_limit_b stack size to use in bytes
+ */
+void
+MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
+ size_t stack_limit_b)
+{
+ daemon->thread_stack_limit_b = stack_limit_b;
+}
+
+
+/**
+ * Set maximum number of concurrent connections to accept. If not
+ * given, MHD will not enforce any limits (modulo running into
+ * OS limits). Values of 0 mean no limit.
+ *
+ * @param daemon daemon to configure
+ * @param global_connection_limit maximum number of (concurrent)
+ connections
+ * @param ip_connection_limit limit on the number of (concurrent)
+ * connections made to the server from the same IP address.
+ * Can be used to prevent one IP from taking over all of
+ * the allowed connections. If the same IP tries to
+ * establish more than the specified number of
+ * connections, they will be immediately rejected.
+ */
+void
+MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
+ unsigned int global_connection_limit,
+ unsigned int ip_connection_limit)
+{
+ daemon->global_connection_limit = global_connection_limit;
+ daemon->ip_connection_limit = ip_connection_limit;
+}
+
+
+/**
+ * After how many seconds of inactivity should a
+ * connection automatically be timed out?
+ * Use zero for no timeout, which is also the (unsafe!) default.
+ *
+ * @param daemon daemon to configure
+ * @param timeout_s number of seconds of timeout to use
+ */
+void
+MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
+ unsigned int timeout_s)
+{
+ daemon->connection_default_timeout = (time_t) timeout_s;
+}
+
+
+/**
+ * Specify a function that should be called for unescaping escape
+ * sequences in URIs and URI arguments. Note that this function
+ * will NOT be used by the `struct MHD_PostProcessor`. If this
+ * option is not specified, the default method will be used which
+ * decodes escape sequences of the form "%HH".
+ *
+ * @param daemon daemon to configure
+ * @param unescape_cb function to use, NULL for default
+ * @param unescape_cb_cls closure for @a unescape_cb
+ */
+void
+MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
+ MHD_UnescapeCallback unescape_cb,
+ void *unescape_cb_cls)
+{
+ daemon->unescape_cb = unescape_cb;
+ daemon->unescape_cb_cls = unescape_cb_cls;
+}
+
+
+/**
+ * Set random values to be used by the Digest Auth module. Note that
+ * the application must ensure that @a buf remains allocated and
+ * unmodified while the daemon is running.
+ *
+ * @param daemon daemon to configure
+ * @param buf_size number of bytes in @a buf
+ * @param buf entropy buffer
+ */
+void
+MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
+ size_t buf_size,
+ const void *buf)
+{
+#if ENABLE_DAUTH
+ daemon->digest_auth_random_buf = buf;
+ daemon->digest_auth_random_buf_size = buf_size;
+#else
+ (void) daemon;
+ (void) buf_size;
+ (void) buf;
+ MHD_PANIC ("Digest authentication not supported by this build.\n");
+#endif
+}
+
+
+/**
+ * Length of the internal array holding the map of the nonce and
+ * the nonce counter.
+ *
+ * @param daemon daemon to configure
+ * @param nc_length desired array length
+ */
+enum MHD_StatusCode
+MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
+ size_t nc_length)
+{
+#if ENABLE_DAUTH
+ if ( ( (size_t) (nc_length * sizeof (struct MHD_NonceNc)))
+ / sizeof (struct MHD_NonceNc) != nc_length)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Specified value for NC_SIZE too large.\n"));
+#endif
+ return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG;
+ }
+ if (0 < nc_length)
+ {
+ if (NULL != daemon->nnc)
+ free (daemon->nnc);
+ daemon->nnc = malloc (daemon->nonce_nc_size
+ * sizeof (struct MHD_NonceNc));
+ if (NULL == daemon->nnc)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to allocate memory for nonce-nc map: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE;
+ }
+ }
+ daemon->digest_nc_length = nc_length;
+ return MHD_SC_OK;
+#else
+ (void) daemon;
+ (void) nc_length;
+ return MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD;
+#endif
+}
+
+
+/* end of daemon_options.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_poll.c
^
|
@@ -0,0 +1,528 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/daemon_poll.c
+ * @brief functions to run poll-based event loop
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_add.h"
+#include "connection_call_handlers.h"
+#include "connection_finish_forward.h"
+#include "daemon_poll.h"
+#include "upgrade_process.h"
+#include "request_resume.h"
+
+
+#ifdef HAVE_POLL
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+
+/**
+ * Set required 'event' members in 'pollfd' elements,
+ * assuming that @a p[0].fd is MHD side of socketpair
+ * and @a p[1].fd is TLS connected socket.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to update
+ */
+static void
+urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ p[0].events = 0;
+ p[1].events = 0;
+
+ if (urh->in_buffer_used < urh->in_buffer_size)
+ p[0].events |= POLLIN;
+ if (0 != urh->out_buffer_used)
+ p[0].events |= POLLOUT;
+
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->out_buffer_used)))
+ p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
+
+ if (urh->out_buffer_used < urh->out_buffer_size)
+ p[1].events |= POLLIN;
+ if (0 != urh->in_buffer_used)
+ p[1].events |= POLLOUT;
+
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_size) ||
+ (0 != urh->in_buffer_used)))
+ p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
+}
+
+
+/**
+ * Set @a p to watch for @a urh.
+ *
+ * @param urh upgrade handle to watch for
+ * @param p pollfd array to set
+ */
+static void
+urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ p[0].fd = urh->connection->socket_fd;
+ p[1].fd = urh->mhd.socket;
+ urh_update_pollfd (urh,
+ p);
+}
+
+
+/**
+ * Update ready state in @a urh based on pollfd.
+ * @param urh upgrade handle to update
+ * @param p 'poll()' processed pollfd.
+ */
+static void
+urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
+{
+ /* Reset read/write ready, preserve error state. */
+ urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
+ urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
+
+ if (0 != (p[0].revents & POLLIN))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (0 != (p[0].revents & POLLOUT))
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (0 != (p[0].revents & POLLHUP))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
+ if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
+ urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+ if (0 != (p[1].revents & POLLIN))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (0 != (p[1].revents & POLLOUT))
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (0 != (p[1].revents & POLLHUP))
+ urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+ if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
+}
+
+
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+
+/**
+ * Process all of our connections and possibly the server
+ * socket using poll().
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
+ bool may_block)
+{
+ unsigned int num_connections;
+ struct MHD_Connection *pos;
+ struct MHD_Connection *prev;
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ struct MHD_UpgradeResponseHandle *urh;
+ struct MHD_UpgradeResponseHandle *urhn;
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+ if ( (! daemon->disallow_suspend_resume) &&
+ (MHD_resume_suspended_connections_ (daemon)) )
+ may_block = false;
+
+ /* count number of connections and thus determine poll set size */
+ num_connections = 0;
+ for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
+ num_connections++;
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
+ num_connections += 2;
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ {
+ MHD_UNSIGNED_LONG_LONG ltimeout;
+ unsigned int i;
+ int timeout;
+ unsigned int poll_server;
+ int poll_listen;
+ int poll_itc_idx;
+ struct pollfd *p;
+ MHD_socket ls;
+
+ p = MHD_calloc_ ((2 + num_connections),
+ sizeof (struct pollfd));
+ if (NULL == p)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_POLL_MALLOC_FAILURE,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ return MHD_SC_POLL_MALLOC_FAILURE;
+ }
+ poll_server = 0;
+ poll_listen = -1;
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) &&
+ (daemon->connections < daemon->global_connection_limit) &&
+ (! daemon->at_limit) )
+ {
+ /* only listen if we are not at the connection limit */
+ p[poll_server].fd = ls;
+ p[poll_server].events = POLLIN;
+ p[poll_server].revents = 0;
+ poll_listen = (int) poll_server;
+ poll_server++;
+ }
+ poll_itc_idx = -1;
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[poll_server].events = POLLIN;
+ p[poll_server].revents = 0;
+ poll_itc_idx = (int) poll_server;
+ poll_server++;
+ }
+ if (! may_block)
+ timeout = 0;
+ else if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ||
+ (MHD_SC_OK != /* FIXME: distinguish between NO_TIMEOUT and errors! */
+ MHD_daemon_get_timeout (daemon,
+ <imeout)) )
+ timeout = -1;
+ else
+ timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
+
+ i = 0;
+ for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
+ {
+ p[poll_server + i].fd = pos->socket_fd;
+ switch (pos->request.event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ timeout = 0; /* clean up "pos" immediately */
+ break;
+ }
+ i++;
+ }
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
+ {
+ urh_to_pollfd (urh,
+ &(p[poll_server + i]));
+ i += 2;
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ if (0 == poll_server + num_connections)
+ {
+ free (p);
+ return MHD_SC_OK;
+ }
+ if (MHD_sys_poll_ (p,
+ poll_server + num_connections,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ {
+ free (p);
+ return MHD_SC_OK;
+ }
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UNEXPECTED_POLL_ERROR,
+ _ ("poll failed: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ free (p);
+ return MHD_SC_UNEXPECTED_POLL_ERROR;
+ }
+
+ /* Reset. New value will be set when connections are processed. */
+ daemon->data_already_pending = false;
+
+ /* handle ITC FD */
+ /* do it before any other processing so
+ new signals will be processed in next loop */
+ if ( (-1 != poll_itc_idx) &&
+ (0 != (p[poll_itc_idx].revents & POLLIN)) )
+ MHD_itc_clear_ (daemon->itc);
+
+ /* handle shutdown */
+ if (daemon->shutdown)
+ {
+ free (p);
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ }
+ i = 0;
+ prev = daemon->connections_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prev;
+ /* first, sanity checks */
+ if (i >= num_connections)
+ break; /* connection list changed somehow, retry later ... */
+ if (p[poll_server + i].fd != pos->socket_fd)
+ continue; /* fd mismatch, something else happened, retry later ... */
+ MHD_connection_call_handlers_ (pos,
+ 0 != (p[poll_server + i].revents & POLLIN),
+ 0 != (p[poll_server + i].revents
+ & POLLOUT),
+ 0 != (p[poll_server + i].revents
+ & MHD_POLL_REVENTS_ERR_DISC));
+ i++;
+ }
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
+ {
+ if (i >= num_connections)
+ break; /* connection list changed somehow, retry later ... */
+
+ /* Get next connection here as connection can be removed
+ * from 'daemon->urh_head' list. */
+ urhn = urh->prev;
+ /* Check for fd mismatch. FIXME: required for safety? */
+ if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
+ (p[poll_server + i + 1].fd != urh->mhd.socket))
+ break;
+ urh_from_pollfd (urh,
+ &p[poll_server + i]);
+ i += 2;
+ MHD_upgrade_response_handle_process_ (urh);
+ /* Finished forwarding? */
+ if ( (0 == urh->in_buffer_size) &&
+ (0 == urh->out_buffer_size) &&
+ (0 == urh->in_buffer_used) &&
+ (0 == urh->out_buffer_used) )
+ {
+ /* MHD_connection_finish_forward_() will remove connection from
+ * 'daemon->urh_head' list. */
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* If 'urh->was_closed' already was set to true, connection will be
+ * moved immediately to cleanup list. Otherwise connection
+ * will stay in suspended list until 'urh' will be marked
+ * with 'was_closed' by application. */
+ MHD_request_resume (&urh->connection->request);
+ }
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ /* handle 'listen' FD */
+ if ( (-1 != poll_listen) &&
+ (0 != (p[poll_listen].revents & POLLIN)) )
+ (void) MHD_accept_connection_ (daemon);
+
+ free (p);
+ }
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Process only the listen socket using poll().
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block true if blocking, false if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
+ bool may_block)
+{
+ struct pollfd p[2];
+ int timeout;
+ unsigned int poll_count;
+ int poll_listen;
+ int poll_itc_idx;
+ MHD_socket ls;
+
+ memset (&p,
+ 0,
+ sizeof (p));
+ poll_count = 0;
+ poll_listen = -1;
+ poll_itc_idx = -1;
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) )
+
+ {
+ p[poll_count].fd = ls;
+ p[poll_count].events = POLLIN;
+ p[poll_count].revents = 0;
+ poll_listen = poll_count;
+ poll_count++;
+ }
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[poll_count].events = POLLIN;
+ p[poll_count].revents = 0;
+ poll_itc_idx = poll_count;
+ poll_count++;
+ }
+
+ if (! daemon->disallow_suspend_resume)
+ (void) MHD_resume_suspended_connections_ (daemon);
+
+ if (! may_block)
+ timeout = 0;
+ else
+ timeout = -1;
+ if (0 == poll_count)
+ return MHD_SC_OK;
+ if (MHD_sys_poll_ (p,
+ poll_count,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_SC_OK;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UNEXPECTED_POLL_ERROR,
+ _ ("poll failed: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_SC_UNEXPECTED_POLL_ERROR;
+ }
+ if ( (-1 != poll_itc_idx) &&
+ (0 != (p[poll_itc_idx].revents & POLLIN)) )
+ MHD_itc_clear_ (daemon->itc);
+
+ /* handle shutdown */
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ if ( (-1 != poll_listen) &&
+ (0 != (p[poll_listen].revents & POLLIN)) )
+ (void) MHD_accept_connection_ (daemon);
+ return MHD_SC_OK;
+}
+
+
+#endif
+
+
+/**
+ * Do poll()-based processing.
+ *
+ * @param daemon daemon to run poll()-loop for
+ * @param may_block true if blocking, false if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_ (struct MHD_Daemon *daemon,
+ bool may_block)
+{
+#ifdef HAVE_POLL
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ return MHD_daemon_poll_all_ (daemon,
+ may_block);
+ return MHD_daemon_poll_listen_socket_ (daemon,
+ may_block);
+#else
+ /* This code should be dead, as we should have checked
+ this earlier... */
+ return MHD_SC_POLL_NOT_SUPPORTED;
+#endif
+}
+
+
+#ifdef HAVE_POLL
+#ifdef HTTPS_SUPPORT
+/**
+ * Process upgraded connection with a poll() loop.
+ * We are in our own thread, only processing @a con
+ *
+ * @param con connection to process
+ */
+void
+MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con)
+{
+ struct MHD_UpgradeResponseHandle *urh = con->request.urh;
+ struct pollfd p[2];
+
+ memset (p,
+ 0,
+ sizeof (p));
+ p[0].fd = urh->connection->socket_fd;
+ p[1].fd = urh->mhd.socket;
+
+ while ( (0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_used) ||
+ (0 != urh->out_buffer_used) )
+ {
+ int timeout;
+
+ urh_update_pollfd (urh,
+ p);
+
+ if ( (con->tls_read_ready) &&
+ (urh->in_buffer_used < urh->in_buffer_size))
+ timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
+ else
+ timeout = -1;
+
+ if (MHD_sys_poll_ (p,
+ 2,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_POLL_ERROR,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ urh_from_pollfd (urh,
+ p);
+ MHD_upgrade_response_handle_process_ (urh);
+ }
+}
+
+
+#endif
+#endif
+
+/* end of daemon_poll.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_poll.h
^
|
@@ -0,0 +1,87 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_poll.h
+ * @brief non-public functions provided by daemon_poll.c
+ * @author Christian Grothoff
+ */
+#ifndef DAEMON_POLL_H
+#define DAEMON_POLL_H
+
+
+#ifdef HAVE_POLL
+/**
+ * Process all of our connections and possibly the server
+ * socket using poll().
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
+ bool may_block)
+MHD_NONNULL (1);
+
+
+/**
+ * Process only the listen socket using poll().
+ *
+ * @param daemon daemon to run poll loop for
+ * @param may_block true if blocking, false if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
+ bool may_block)
+MHD_NONNULL (1);
+
+
+/**
+ * Do poll()-based processing.
+ *
+ * @param daemon daemon to run poll()-loop for
+ * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_poll_ (struct MHD_Daemon *daemon,
+ bool may_block)
+MHD_NONNULL (1);
+
+#endif
+
+
+#ifdef HTTPS_SUPPORT
+#ifdef HAVE_POLL
+/**
+ * Process upgraded connection with a poll() loop.
+ * We are in our own thread, only processing @a con
+ *
+ * @param con connection to process
+ */
+void
+MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con)
+MHD_NONNULL (1);
+
+#endif
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_quiesce.c
^
|
@@ -0,0 +1,128 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_quiesce.c
+ * @brief main functions to quiesce a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Stop accepting connections from the listening socket. Allows
+ * clients to continue processing, but stops accepting new
+ * connections. Note that the caller is responsible for closing the
+ * returned socket; however, if MHD is run using threads (anything but
+ * external select mode), it must not be closed until AFTER
+ * #MHD_stop_daemon has been called (as it is theoretically possible
+ * that an existing thread is still using it).
+ *
+ * Note that some thread modes require the caller to have passed
+ * #MHD_USE_ITC when using this API. If this daemon is
+ * in one of those modes and this option was not given to
+ * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.
+ *
+ * @param daemon daemon to stop accepting new connections for
+ * @return old listen socket on success, #MHD_INVALID_SOCKET if
+ * the daemon was already not listening anymore, or
+ * was never started
+ * @ingroup specialized
+ */
+MHD_socket
+MHD_daemon_quiesce (struct MHD_Daemon *daemon)
+{
+ MHD_socket listen_socket;
+
+ if (MHD_INVALID_SOCKET == (listen_socket = daemon->listen_socket))
+ return MHD_INVALID_SOCKET;
+ if ( (daemon->disable_itc) &&
+ (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC,
+ "Using MHD_quiesce_daemon in this mode requires ITC.\n");
+#endif
+ return MHD_INVALID_SOCKET;
+ }
+
+ if (NULL != daemon->worker_pool)
+ {
+ unsigned int i;
+
+ for (i = 0; i < daemon->worker_pool_size; i++)
+ {
+ struct MHD_Daemon *worker = &daemon->worker_pool[i];
+
+ worker->was_quiesced = true;
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (-1 != worker->epoll_fd) &&
+ (worker->listen_socket_in_epoll) )
+ {
+ if (0 != epoll_ctl (worker->epoll_fd,
+ EPOLL_CTL_DEL,
+ listen_socket,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
+ worker->listen_socket_in_epoll = false;
+ }
+ else
+#endif
+ if (MHD_ITC_IS_VALID_ (worker->itc))
+ {
+ if (! MHD_itc_activate_ (worker->itc,
+ "q"))
+ MHD_PANIC (_ (
+ "Failed to signal quiesce via inter-thread communication channel.\n"));
+ }
+ }
+ daemon->was_quiesced = true;
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (-1 != daemon->epoll_fd) &&
+ (daemon->listen_socket_in_epoll) )
+ {
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ listen_socket,
+ NULL))
+ MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
+ daemon->listen_socket_in_epoll = false;
+ }
+#endif
+ }
+
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc,
+ "q")) )
+ MHD_PANIC (_ (
+ "Failed to signal quiesce via inter-thread communication channel.\n"));
+
+ /* FIXME: we might want some bi-directional communication here
+ (in both the thread-pool and single-thread case!)
+ to be sure that the threads have stopped using the listen
+ socket, otherwise there is still the possibility of a race
+ between a thread accept()ing and the caller closing and
+ re-binding the socket. */return listen_socket;
+}
+
+
+/* end of daemon_quiesce.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_run.c
^
|
@@ -0,0 +1,83 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_run.c
+ * @brief generic function to run event loop of a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_cleanup.h"
+#include "daemon_epoll.h"
+#include "daemon_poll.h"
+#include "daemon_select.h"
+
+
+/**
+ * Run webserver operations (without blocking unless in client
+ * callbacks). This method should be called by clients in combination
+ * with #MHD_get_fdset if the client-controlled select method is used
+ * and #MHD_get_timeout().
+ *
+ * This function is a convenience method, which is useful if the
+ * fd_sets from #MHD_get_fdset were not directly passed to `select()`;
+ * with this function, MHD will internally do the appropriate `select()`
+ * call itself again. While it is always safe to call #MHD_run (if
+ * #MHD_USE_INTERNAL_POLLING_THREAD is not set), you should call
+ * #MHD_run_from_select if performance is important (as it saves an
+ * expensive call to `select()`).
+ *
+ * @param daemon daemon to run
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_run (struct MHD_Daemon *daemon)
+{
+ enum MHD_StatusCode sc;
+
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
+ return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL;
+ switch (daemon->event_loop_syscall)
+ {
+ case MHD_ELS_POLL:
+ sc = MHD_daemon_poll_ (daemon,
+ MHD_NO);
+ MHD_connection_cleanup_ (daemon);
+ return sc;
+#ifdef EPOLL_SUPPORT
+ case MHD_ELS_EPOLL:
+ sc = MHD_daemon_epoll_ (daemon,
+ MHD_NO);
+ MHD_connection_cleanup_ (daemon);
+ return sc;
+#endif
+ case MHD_ELS_SELECT:
+ return MHD_daemon_select_ (daemon,
+ MHD_NO);
+ /* MHD_select does MHD_connection_cleanup_ already */
+ default:
+ return MHD_SC_CONFIGURATION_UNEXPECTED_ELS;
+ }
+}
+
+
+/* end of daemon_run.c */
|
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_run_from_select.c
^
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_select.c
^
|
@@ -0,0 +1,821 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_select.c
+ * @brief function to run select()-based event loop of a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_add.h"
+#include "connection_call_handlers.h"
+#include "connection_cleanup.h"
+#include "connection_finish_forward.h"
+#include "daemon_select.h"
+#include "daemon_epoll.h"
+#include "request_resume.h"
+#include "upgrade_process.h"
+
+
+/**
+ * We defined a macro with the same name as a function we
+ * are implementing here. Need to undef the macro to avoid
+ * causing a conflict.
+ */
+#undef MHD_daemon_get_fdset
+
+/**
+ * Obtain the `select()` sets for this daemon. Daemon's FDs will be
+ * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO
+ * for each fd_set before calling this function. FD_SETSIZE is assumed
+ * to be platform's default.
+ *
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'. In the latter
+ * case, it will only add the single 'epoll()' file descriptor used by
+ * MHD to the sets. It's necessary to use #MHD_daemon_get_timeout() in
+ * combination with this function.
+ *
+ * This function must be called only for daemon started without
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @return #MHD_SC_OK on success, otherwise error code
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd)
+{
+ return MHD_daemon_get_fdset2 (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ _MHD_SYS_DEFAULT_FD_SETSIZE);
+}
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Obtain the select() file descriptor sets for the
+ * given @a urh.
+ *
+ * @param urh upgrade handle to wait for
+ * @param[out] rs read set to initialize
+ * @param[out] ws write set to initialize
+ * @param[out] es except set to initialize
+ * @param[out] max_fd maximum FD to update
+ * @param fd_setsize value of FD_SETSIZE
+ * @return true on success, false on error
+ */
+static bool
+urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
+ fd_set *rs,
+ fd_set *ws,
+ fd_set *es,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+{
+ const MHD_socket conn_sckt = urh->connection->socket_fd;
+ const MHD_socket mhd_sckt = urh->mhd.socket;
+ bool res = true;
+
+ /* Do not add to 'es' only if socket is closed
+ * or not used anymore. */
+ if (MHD_INVALID_SOCKET != conn_sckt)
+ {
+ if ( (urh->in_buffer_used < urh->in_buffer_size) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->out_buffer_used) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->out_buffer_used)))
+ MHD_add_to_fd_set_ (conn_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
+ if (MHD_INVALID_SOCKET != mhd_sckt)
+ {
+ if ( (urh->out_buffer_used < urh->out_buffer_size) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->in_buffer_used) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_size) ||
+ (0 != urh->in_buffer_used)))
+ MHD_add_to_fd_set_ (mhd_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
+
+ return res;
+}
+
+
+#endif
+
+
+/**
+ * Internal version of #MHD_daemon_get_fdset2().
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+static enum MHD_StatusCode
+internal_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+
+{
+ struct MHD_Connection *pos;
+ struct MHD_Connection *posn;
+ enum MHD_StatusCode result = MHD_SC_OK;
+ MHD_socket ls;
+
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+
+ ls = daemon->listen_socket;
+ if ( (MHD_INVALID_SOCKET != ls) &&
+ (! daemon->was_quiesced) &&
+ (! MHD_add_to_fd_set_ (ls,
+ read_fd_set,
+ max_fd,
+ fd_setsize)) )
+ result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+
+ /* Add all sockets to 'except_fd_set' as well to watch for
+ * out-of-band data. However, ignore errors if INFO_READ
+ * or INFO_WRITE sockets will not fit 'except_fd_set'. */
+ /* Start from oldest connections. Make sense for W32 FDSETs. */
+ for (pos = daemon->connections_tail; NULL != pos; pos = posn)
+ {
+ posn = pos->prev;
+
+ switch (pos->request.event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+#ifdef MHD_POSIX_SOCKETS
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ write_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+#ifdef MHD_POSIX_SOCKETS
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+#endif /* MHD_POSIX_SOCKETS */
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ if ( (NULL == except_fd_set) ||
+ ! MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* this should never happen */
+ break;
+ }
+ }
+#ifdef MHD_WINSOCK_SOCKETS
+ /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
+ * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
+ * not be pushed out. */
+ for (pos = daemon->connections_tail; NULL != pos; pos = posn)
+ {
+ posn = pos->prev;
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+ }
+#endif /* MHD_WINSOCK_SOCKETS */
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ {
+ struct MHD_UpgradeResponseHandle *urh;
+
+ for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
+ {
+ if (! urh_to_fdset (urh,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ }
+ }
+#endif
+ return result;
+}
+
+
+/**
+ * Obtain the `select()` sets for this daemon. Daemon's FDs will be
+ * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO
+ * for each fd_set before calling this function.
+ *
+ * Passing custom FD_SETSIZE as @a fd_setsize allow usage of
+ * larger/smaller than platform's default fd_sets.
+ *
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'. In the latter
+ * case, it will only add the single 'epoll' file descriptor used by
+ * MHD to the sets. It's necessary to use #MHD_get_timeout() in
+ * combination with this function.
+ *
+ * This function must be called only for daemon started
+ * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to get sets from
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @param max_fd increased to largest FD added (if larger
+ * than existing value); can be NULL
+ * @param fd_setsize value of FD_SETSIZE
+ * @return #MHD_SC_OK on success, otherwise error code
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+{
+ if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
+ (MHD_ELS_POLL == daemon->event_loop_syscall) )
+ return MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_FDSET;
+
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+
+ /* we're in epoll mode, use the epoll FD as a stand-in for
+ the entire event set */
+
+ return MHD_add_to_fd_set_ (daemon->epoll_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize)
+ ? MHD_SC_OK
+ : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ }
+#endif
+
+ return internal_get_fdset2 (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+}
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Update the @a urh based on the ready FDs in
+ * the @a rs, @a ws, and @a es.
+ *
+ * @param urh upgrade handle to update
+ * @param rs read result from select()
+ * @param ws write result from select()
+ * @param es except result from select()
+ */
+static void
+urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
+ const fd_set *rs,
+ const fd_set *ws,
+ const fd_set *es)
+{
+ const MHD_socket conn_sckt = urh->connection->socket_fd;
+ const MHD_socket mhd_sckt = urh->mhd.socket;
+
+ /* Reset read/write ready, preserve error state. */
+ urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
+ urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
+
+ if (MHD_INVALID_SOCKET != conn_sckt)
+ {
+ if (FD_ISSET (conn_sckt, rs))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (conn_sckt, ws))
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (conn_sckt, es))
+ urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+ }
+ if ((MHD_INVALID_SOCKET != mhd_sckt))
+ {
+ if (FD_ISSET (mhd_sckt, rs))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (mhd_sckt, ws))
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (mhd_sckt, es))
+ urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+ }
+}
+
+
+#endif
+
+
+/**
+ * Internal version of #MHD_run_from_select().
+ *
+ * @param daemon daemon to run select loop for
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+static enum MHD_StatusCode
+internal_run_from_select (struct MHD_Daemon *daemon,
+ const fd_set *read_fd_set,
+ const fd_set *write_fd_set,
+ const fd_set *except_fd_set)
+{
+ MHD_socket ds;
+ struct MHD_Connection *pos;
+ struct MHD_Connection *prev;
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ struct MHD_UpgradeResponseHandle *urh;
+ struct MHD_UpgradeResponseHandle *urhn;
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ /* Reset. New value will be set when connections are processed. */
+ /* Note: no-op for thread-per-connection as it is always false in that mode. */
+ daemon->data_already_pending = false;
+
+ /* Clear ITC to avoid spinning select */
+ /* Do it before any other processing so new signals
+ will trigger select again and will be processed */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
+ read_fd_set)) )
+ MHD_itc_clear_ (daemon->itc);
+
+ /* select connection thread handling type */
+ if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) &&
+ (FD_ISSET (ds,
+ read_fd_set)) )
+ (void) MHD_accept_connection_ (daemon);
+
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ {
+ /* do not have a thread per connection, process all connections now */
+ prev = daemon->connections_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prev;
+ ds = pos->socket_fd;
+ if (MHD_INVALID_SOCKET == ds)
+ continue;
+ MHD_connection_call_handlers_ (pos,
+ FD_ISSET (ds,
+ read_fd_set),
+ FD_ISSET (ds,
+ write_fd_set),
+ FD_ISSET (ds,
+ except_fd_set));
+ }
+ }
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ /* handle upgraded HTTPS connections */
+ for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
+ {
+ urhn = urh->prev;
+ /* update urh state based on select() output */
+ urh_from_fdset (urh,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set);
+ /* call generic forwarding function for passing data */
+ MHD_upgrade_response_handle_process_ (urh);
+ /* Finished forwarding? */
+ if ( (0 == urh->in_buffer_size) &&
+ (0 == urh->out_buffer_size) &&
+ (0 == urh->in_buffer_used) &&
+ (0 == urh->out_buffer_used) )
+ {
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* Resuming will move connection to cleanup list. */
+ MHD_request_resume (&urh->connection->request);
+ }
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ MHD_connection_cleanup_ (daemon);
+ return MHD_SC_OK;
+}
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Process upgraded connection with a select loop.
+ * We are in our own thread, only processing @a con
+ *
+ * @param con connection to process
+ */
+void
+MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
+{
+ struct MHD_UpgradeResponseHandle *urh = con->request.urh;
+
+ while ( (0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_used) ||
+ (0 != urh->out_buffer_used) )
+ {
+ /* use select */
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket max_fd;
+ int num_ready;
+ bool result;
+
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ max_fd = MHD_INVALID_SOCKET;
+ result = urh_to_fdset (urh,
+ &rs,
+ &ws,
+ &es,
+ &max_fd,
+ FD_SETSIZE);
+ if (! result)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
+ _ ("Error preparing select.\n"));
+#endif
+ break;
+ }
+ /* FIXME: does this check really needed? */
+ if (MHD_INVALID_SOCKET != max_fd)
+ {
+ struct timeval*tvp;
+ struct timeval tv;
+ if ( (con->tls_read_ready) &&
+ (urh->in_buffer_used < urh->in_buffer_size))
+ { /* No need to wait if incoming data is already pending in TLS buffers. */
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ else
+ tvp = NULL;
+ num_ready = MHD_SYS_select_ (max_fd + 1,
+ &rs,
+ &ws,
+ &es,
+ tvp);
+ }
+ else
+ num_ready = 0;
+ if (num_ready < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ MHD_SC_UNEXPECTED_SELECT_ERROR,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ urh_from_fdset (urh,
+ &rs,
+ &ws,
+ &es);
+ MHD_upgrade_response_handle_process_ (urh);
+ }
+}
+
+
+#endif
+
+
+/**
+ * Run webserver operations. This method should be called by clients
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
+ *
+ * You can use this function instead of #MHD_run if you called
+ * `select()` on the result from #MHD_get_fdset. File descriptors in
+ * the sets that are not controlled by MHD will be ignored. Calling
+ * this function instead of #MHD_run is more efficient as MHD will not
+ * have to call `select()` again to determine which operations are
+ * ready.
+ *
+ * This function cannot be used with daemon started with
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
+ * @param daemon daemon to run select loop for
+ * @param read_fd_set read set
+ * @param write_fd_set write set
+ * @param except_fd_set except set
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
+ const fd_set *read_fd_set,
+
+
+ const fd_set *write_fd_set,
+ const fd_set *except_fd_set)
+{
+ if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
+ (MHD_ELS_POLL == daemon->event_loop_syscall) )
+ return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_SELECT;
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+#ifdef EPOLL_SUPPORT
+ enum MHD_StatusCode sc;
+
+ sc = MHD_daemon_epoll_ (daemon,
+ MHD_NO);
+ MHD_connection_cleanup_ (daemon);
+ return sc;
+#else /* ! EPOLL_SUPPORT */
+ return MHD_NO;
+#endif /* ! EPOLL_SUPPORT */
+ }
+
+ /* Resuming external connections when using an extern mainloop */
+ if (! daemon->disallow_suspend_resume)
+ (void) MHD_resume_suspended_connections_ (daemon);
+
+ return internal_run_from_select (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set);
+}
+
+
+/**
+ * Main internal select() call. Will compute select sets, call
+ * select() and then #internal_run_from_select() with the result.
+ *
+ * @param daemon daemon to run select() loop for
+ * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_select_ (struct MHD_Daemon *daemon,
+ int may_block)
+{
+ int num_ready;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxsock;
+ struct timeval timeout;
+ struct timeval *tv;
+ MHD_UNSIGNED_LONG_LONG ltimeout;
+ MHD_socket ls;
+ enum MHD_StatusCode sc;
+ enum MHD_StatusCode sc2;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ maxsock = MHD_INVALID_SOCKET;
+ sc = MHD_SC_OK;
+ if ( (! daemon->disallow_suspend_resume) &&
+ (MHD_resume_suspended_connections_ (daemon)) &&
+ (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
+ may_block = MHD_NO;
+
+ if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
+ {
+
+ /* single-threaded, go over everything */
+ if (MHD_SC_OK !=
+ (sc = internal_get_fdset2 (daemon,
+ &rs,
+ &ws,
+ &es,
+ &maxsock,
+ FD_SETSIZE)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ sc,
+ _ ("Could not obtain daemon fdsets.\n"));
+#endif
+ }
+ }
+ else
+ {
+ /* accept only, have one thread per connection */
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) &&
+ (! MHD_add_to_fd_set_ (ls,
+ &rs,
+ &maxsock,
+ FD_SETSIZE)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
+ _ ("Could not add listen socket to fdset.\n"));
+#endif
+ return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+ }
+ }
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ &maxsock,
+ FD_SETSIZE)) )
+ {
+#if defined(MHD_WINSOCK_SOCKETS)
+ /* fdset limit reached, new connections
+ cannot be handled. Remove listen socket FD
+ from fdset and retry to add ITC FD. */
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (! daemon->was_quiesced) )
+ {
+ FD_CLR (ls,
+ &rs);
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ {
+#endif /* MHD_WINSOCK_SOCKETS */
+ sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ sc,
+ _ (
+ "Could not add control inter-thread communication channel FD to fdset.\n"));
+#endif
+#if defined(MHD_WINSOCK_SOCKETS)
+ }
+}
+
+
+#endif /* MHD_WINSOCK_SOCKETS */
+ }
+ /* Stop listening if we are at the configured connection limit */
+ /* If we're at the connection limit, no point in really
+ accepting new connections; however, make sure we do not miss
+ the shutdown OR the termination of an existing connection; so
+ only do this optimization if we have a signaling ITC in
+ place. */
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
+ (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ ( (daemon->connections == daemon->global_connection_limit) ||
+ (daemon->at_limit) ) )
+ {
+ FD_CLR (ls,
+ &rs);
+ }
+ tv = NULL;
+ if (MHD_SC_OK != sc)
+ may_block = MHD_NO;
+ if (MHD_NO == may_block)
+ {
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ tv = &timeout;
+ }
+ else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
+ (MHD_SC_OK ==
+ MHD_daemon_get_timeout (daemon,
+ <imeout)) )
+ {
+ /* ltimeout is in ms */
+ timeout.tv_usec = (ltimeout % 1000) * 1000;
+ if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
+ timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
+ else
+ timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
+ tv = &timeout;
+ }
+ num_ready = MHD_SYS_select_ (maxsock + 1,
+ &rs,
+ &ws,
+ &es,
+ tv);
+ if (daemon->shutdown)
+ return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
+ if (num_ready < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return sc;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UNEXPECTED_SELECT_ERROR,
+ _ ("select failed: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ return MHD_SC_UNEXPECTED_SELECT_ERROR;
+ }
+ if (MHD_SC_OK !=
+ (sc2 = internal_run_from_select (daemon,
+ &rs,
+ &ws,
+ &es)))
+ return sc2;
+ return sc;
+}
+
+/* end of daemon_select.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_select.h
^
|
@@ -0,0 +1,56 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_select.h
+ * @brief non-public functions provided by daemon_select.c
+ * @author Christian Grothoff
+ */
+
+#ifndef DAEMON_SELECT_H
+#define DAEMON_SELECT_H
+
+/**
+ * Main internal select() call. Will compute select sets, call
+ * select() and then #internal_run_from_select() with the result.
+ *
+ * @param daemon daemon to run select() loop for
+ * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @return #MHD_SC_OK on success
+ */
+enum MHD_StatusCode
+MHD_daemon_select_ (struct MHD_Daemon *daemon,
+ int may_block)
+MHD_NONNULL (1);
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Process upgraded connection with a select loop.
+ * We are in our own thread, only processing @a con
+ *
+ * @param con connection to process
+ */
+void
+MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
+MHD_NONNULL (1);
+
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/daemon_start.c
^
|
@@ -0,0 +1,975 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/daemon_start.c
+ * @brief functions to start a daemon
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_cleanup.h"
+#include "daemon_close_all_connections.h"
+#include "daemon_select.h"
+#include "daemon_poll.h"
+#include "daemon_epoll.h"
+#include "request_resume.h"
+
+
+/**
+ * Set listen socket options to allow port rebinding (or not)
+ * depending on how MHD was configured.
+ *
+ * @param[in,out] daemon the daemon with the listen socket to configure
+ * @return #MHD_SC_OK on success (or non-fatal errors)
+ */
+static enum MHD_StatusCode
+configure_listen_reuse (struct MHD_Daemon *daemon)
+{
+ const MHD_SCKT_OPT_BOOL_ on = 1;
+
+ /* Apply the socket options according to
+ listening_address_reuse. */
+ if (daemon->allow_address_reuse)
+ {
+ /* User requested to allow reusing listening address:port. */
+#ifndef MHD_WINSOCK_SOCKETS
+ /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
+ * it doesn't work. */
+ if (0 > setsockopt (daemon->listen_socket,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (void *) &on,
+ sizeof (on)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
+ }
+ return MHD_SC_OK;
+#endif /* ! MHD_WINSOCK_SOCKETS */
+ /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
+ * Fail if SO_REUSEPORT is not defined or setsockopt fails.
+ */
+ /* SO_REUSEADDR on W32 has the same semantics
+ as SO_REUSEPORT on BSD/Linux */
+#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
+ if (0 > setsockopt (daemon->listen_socket,
+ SOL_SOCKET,
+#ifndef MHD_WINSOCK_SOCKETS
+ SO_REUSEPORT,
+#else /* MHD_WINSOCK_SOCKETS */
+ SO_REUSEADDR,
+#endif /* MHD_WINSOCK_SOCKETS */
+ (void *) &on,
+ sizeof (on)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
+ }
+ return MHD_SC_OK;
+#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
+ /* we're supposed to allow address:port re-use, but
+ on this platform we cannot; fail hard */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED,
+ _ (
+ "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
+#endif
+ return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED;
+#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
+ }
+
+ /* if (! daemon->allow_address_reuse) */
+ /* User requested to disallow reusing listening address:port.
+ * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
+ * is used and Solaris with SO_EXCLBIND.
+ * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
+ * or setsockopt fails.
+ */
+#if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
+ (defined(__sun) && defined(SO_EXCLBIND))
+ if (0 > setsockopt (daemon->listen_socket,
+ SOL_SOCKET,
+#ifdef SO_EXCLUSIVEADDRUSE
+ SO_EXCLUSIVEADDRUSE,
+#else /* SO_EXCLBIND */
+ SO_EXCLBIND,
+#endif /* SO_EXCLBIND */
+ (void *) &on,
+ sizeof (on)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
+ }
+ return MHD_SC_OK;
+#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED,
+ _ (
+ "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
+#endif
+ return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
+#endif /* MHD_WINSOCK_SOCKETS */
+ /* Not on WINSOCK, simply doing nothing will do */
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Open, configure and bind the listen socket (if required).
+ *
+ * @param[in,out] daemon daemon to open the socket for
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+open_listen_socket (struct MHD_Daemon *daemon)
+{
+ enum MHD_StatusCode sc;
+ socklen_t addrlen;
+ struct sockaddr_storage ss;
+ const struct sockaddr *sa;
+ int pf;
+ bool use_v6;
+
+ if (MHD_INVALID_SOCKET != daemon->listen_socket)
+ return MHD_SC_OK; /* application opened it for us! */
+ pf = -1;
+ /* Determine address family */
+ switch (daemon->listen_af)
+ {
+ case MHD_AF_NONE:
+ if (0 == daemon->listen_sa_len)
+ {
+ /* no listening desired, that's OK */
+ return MHD_SC_OK;
+ }
+ /* we have a listen address, get AF from there! */
+ switch (daemon->listen_sa.ss_family)
+ {
+ case AF_INET:
+ pf = PF_INET;
+ use_v6 = false;
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ pf = PF_INET6;
+ use_v6 = true;
+ break;
+#endif
+#ifdef AF_UNIX
+ case AF_UNIX:
+ pf = PF_UNIX;
+ use_v6 = false;
+ break;
+#endif
+ default:
+ return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
+ } /* switch on ss_family */
+ break; /* MHD_AF_NONE */
+ case MHD_AF_AUTO:
+#if HAVE_INET6
+ pf = PF_INET6;
+ use_v6 = true;
+#else
+ pf = PF_INET;
+ use_v6 = false;
+#endif
+ break;
+ case MHD_AF_INET4:
+ use_v6 = false;
+ pf = PF_INET;
+ break;
+ case MHD_AF_INET6:
+ case MHD_AF_DUAL:
+#if HAVE_INET6
+ pf = PF_INET6;
+ use_v6 = true;
+ break;
+#else
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
+ _ ("IPv6 not supported by this build.\n"));
+#endif
+ return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
+#endif
+ }
+ mhd_assert (-1 != pf);
+ /* try to open listen socket */
+try_open_listen_socket:
+ daemon->listen_socket = MHD_socket_create_listen_ (pf);
+ if ( (MHD_INVALID_SOCKET == daemon->listen_socket) &&
+ (MHD_AF_AUTO == daemon->listen_af) &&
+ (use_v6) )
+ {
+ use_v6 = false;
+ pf = PF_INET;
+ goto try_open_listen_socket;
+ }
+ if (MHD_INVALID_SOCKET == daemon->listen_socket)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET,
+ _ ("Failed to create socket for listening: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET;
+ }
+
+ if (MHD_SC_OK !=
+ (sc = configure_listen_reuse (daemon)))
+ return sc;
+
+ /* configure for dual stack (or not) */
+ if (use_v6)
+ {
+#if defined IPPROTO_IPV6 && defined IPV6_V6ONLY
+ /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
+ (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
+ and may also be missing on older POSIX systems; good luck if you have any of those,
+ your IPv6 socket may then also bind against IPv4 anyway... */
+ const MHD_SCKT_OPT_BOOL_ v6_only =
+ (MHD_AF_INET6 == daemon->listen_af);
+ if (0 > setsockopt (daemon->listen_socket,
+ IPPROTO_IPV6,
+ IPV6_V6ONLY,
+ (const void *) &v6_only,
+ sizeof (v6_only)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ }
+#else
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED,
+ _ (
+ "Cannot explicitly setup dual stack behavior on this platform.\n"));
+#endif
+#endif
+ }
+
+ /* Determine address to bind to */
+ if (0 != daemon->listen_sa_len)
+ {
+ /* Bind address explicitly given */
+ sa = (const struct sockaddr *) &daemon->listen_sa;
+ addrlen = daemon->listen_sa_len;
+ }
+ else
+ {
+ /* Compute bind address based on port and AF */
+#if HAVE_INET6
+ if (use_v6)
+ {
+#ifdef IN6ADDR_ANY_INIT
+ static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
+#endif
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
+
+ addrlen = sizeof (struct sockaddr_in6);
+ memset (sin6,
+ 0,
+ sizeof (struct sockaddr_in6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons (daemon->listen_port);
+#ifdef IN6ADDR_ANY_INIT
+ sin6->sin6_addr = static_in6any;
+#endif
+#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
+ sin6->sin6_len = sizeof (struct sockaddr_in6);
+#endif
+ }
+ else
+#endif
+ {
+ struct sockaddr_in *sin4 = (struct sockaddr_in *) &ss;
+
+ addrlen = sizeof (struct sockaddr_in);
+ memset (sin4,
+ 0,
+ sizeof (struct sockaddr_in));
+ sin4->sin_family = AF_INET;
+ sin4->sin_port = htons (daemon->listen_port);
+ if (0 != INADDR_ANY)
+ sin4->sin_addr.s_addr = htonl (INADDR_ANY);
+#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ sin4->sin_len = sizeof (struct sockaddr_in);
+#endif
+ }
+ sa = (const struct sockaddr *) &ss;
+ }
+
+ /* actually do the bind() */
+ if (-1 == bind (daemon->listen_socket,
+ sa,
+ addrlen))
+ {
+#ifdef HAVE_MESSAGES
+ unsigned int port = 0;
+
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ if (addrlen == sizeof (struct sockaddr_in))
+ port = ntohs (((const struct sockaddr_in *) sa)->sin_port);
+ else
+ port = UINT16_MAX + 1; /* indicate size error */
+ break;
+ case AF_INET6:
+ if (addrlen == sizeof (struct sockaddr_in6))
+ port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port);
+ else
+ port = UINT16_MAX + 1; /* indicate size error */
+ break;
+ default:
+ port = UINT_MAX; /* AF_UNIX? */
+ break;
+ }
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_SOCKET_BIND_FAILED,
+ _ ("Failed to bind to port %u: %s\n"),
+ port,
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_LISTEN_SOCKET_BIND_FAILED;
+ }
+
+ /* setup TCP_FASTOPEN */
+#ifdef TCP_FASTOPEN
+ if (MHD_FOM_DISABLE != daemon->fast_open_method)
+ {
+ if (0 != setsockopt (daemon->listen_socket,
+ IPPROTO_TCP,
+ TCP_FASTOPEN,
+ &daemon->fo_queue_length,
+ sizeof (daemon->fo_queue_length)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_FAST_OPEN_FAILURE,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ if (MHD_FOM_REQUIRE == daemon->fast_open_method)
+ return MHD_SC_FAST_OPEN_FAILURE;
+ }
+ }
+#endif
+
+ /* setup listening */
+ if (0 > listen (daemon->listen_socket,
+ daemon->listen_backlog))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_FAILURE,
+ _ ("Failed to listen for connections: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_LISTEN_FAILURE;
+ }
+ return MHD_SC_OK;
+}
+
+
+/**
+ * Obtain the listen port number from the socket (if it
+ * was not explicitly set by us, i.e. if we were given
+ * a listen socket or if the port was 0 and the OS picked
+ * a free one).
+ *
+ * @param[in,out] daemon daemon to obtain the port number for
+ */
+static void
+get_listen_port_number (struct MHD_Daemon *daemon)
+{
+ struct sockaddr_storage servaddr;
+ socklen_t addrlen;
+
+ if ( (0 != daemon->listen_port) ||
+ (MHD_INVALID_SOCKET == daemon->listen_socket) )
+ return; /* nothing to be done */
+
+ memset (&servaddr,
+ 0,
+ sizeof (struct sockaddr_storage));
+ addrlen = sizeof (servaddr);
+ if (0 != getsockname (daemon->listen_socket,
+ (struct sockaddr *) &servaddr,
+ &addrlen))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
+ _ ("Failed to get listen port number: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif /* HAVE_MESSAGES */
+ return;
+ }
+#ifdef MHD_POSIX_SOCKETS
+ if (sizeof (servaddr) < addrlen)
+ {
+ /* should be impossible with `struct sockaddr_storage` */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
+ _ (
+ "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
+#endif /* HAVE_MESSAGES */
+ return;
+ }
+#endif /* MHD_POSIX_SOCKETS */
+ switch (servaddr.ss_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
+
+ daemon->listen_port = ntohs (s4->sin_port);
+ break;
+ }
+#ifdef HAVE_INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
+
+ daemon->listen_port = ntohs (s6->sin6_port);
+ break;
+ }
+#endif /* HAVE_INET6 */
+#ifdef AF_UNIX
+ case AF_UNIX:
+ daemon->listen_port = 0; /* special value for UNIX domain sockets */
+ break;
+#endif
+ default:
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
+ _ ("Unknown address family!\n"));
+#endif
+ daemon->listen_port = 0; /* ugh */
+ break;
+ }
+}
+
+
+#ifdef EPOLL_SUPPORT
+/**
+ * Setup file descriptor to be used for epoll() control.
+ *
+ * @param daemon the daemon to setup epoll FD for
+ * @return the epoll() fd to use
+ */
+static int
+setup_epoll_fd (struct MHD_Daemon *daemon)
+{
+ int fd;
+
+#ifndef HAVE_MESSAGES
+ (void) daemon; /* Mute compiler warning. */
+#endif /* ! HAVE_MESSAGES */
+
+#ifdef USE_EPOLL_CREATE1
+ fd = epoll_create1 (EPOLL_CLOEXEC);
+#else /* ! USE_EPOLL_CREATE1 */
+ fd = epoll_create (MAX_EVENTS);
+#endif /* ! USE_EPOLL_CREATE1 */
+ if (MHD_INVALID_SOCKET == fd)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_CREATE_FAILED,
+ _ ("Call to epoll_create1 failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_INVALID_SOCKET;
+ }
+#if ! defined(USE_EPOLL_CREATE1)
+ if (! MHD_socket_noninheritable_ (fd))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
+ _ ("Failed to set noninheritable mode on epoll FD.\n"));
+#endif
+ }
+#endif /* ! USE_EPOLL_CREATE1 */
+ return fd;
+}
+
+
+/**
+ * Setup epoll() FD for the daemon and initialize it to listen
+ * on the listen FD.
+ * @remark To be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon daemon to initialize for epoll()
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+setup_epoll_to_listen (struct MHD_Daemon *daemon)
+{
+ struct epoll_event event;
+ MHD_socket ls;
+
+ /* FIXME: update function! */
+ daemon->epoll_fd = setup_epoll_fd (daemon);
+ if (-1 == daemon->epoll_fd)
+ return MHD_SC_EPOLL_CTL_CREATE_FAILED;
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if (! daemon->disallow_upgrade)
+ {
+ daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
+ if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
+ return MHD_SC_EPOLL_CTL_CREATE_FAILED;
+ }
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) ||
+ (daemon->was_quiesced) )
+ return MHD_SC_OK; /* non-listening daemon */
+ event.events = EPOLLIN;
+ event.data.ptr = daemon;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ ls,
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_EPOLL_CTL_ADD_FAILED;
+ }
+ daemon->listen_socket_in_epoll = true;
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = (void *) daemon->epoll_itc_marker;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ MHD_itc_r_fd_ (daemon->itc),
+ &event))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_SC_EPOLL_CTL_ADD_FAILED;
+ }
+ }
+ return MHD_SC_OK;
+}
+
+
+#endif
+
+
+/**
+ * Thread that runs the polling loop until the daemon
+ * is explicitly shut down.
+ *
+ * @param cls `struct MHD_Deamon` to run select loop in a thread for
+ * @return always 0 (on shutdown)
+ */
+static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
+MHD_polling_thread (void *cls)
+{
+ struct MHD_Daemon *daemon = cls;
+
+ MHD_thread_init_ (&daemon->pid);
+ while (! daemon->shutdown)
+ {
+ switch (daemon->event_loop_syscall)
+ {
+ case MHD_ELS_AUTO:
+ MHD_PANIC ("MHD_ELS_AUTO should have been mapped to preferred style.\n");
+ break;
+ case MHD_ELS_SELECT:
+ MHD_daemon_select_ (daemon,
+ MHD_YES);
+ break;
+ case MHD_ELS_POLL:
+#if HAVE_POLL
+ MHD_daemon_poll_ (daemon,
+ MHD_YES);
+#else
+ MHD_PANIC ("MHD_ELS_POLL not supported, should have failed earlier.\n");
+#endif
+ break;
+ case MHD_ELS_EPOLL:
+#ifdef EPOLL_SUPPORT
+ MHD_daemon_epoll_ (daemon,
+ MHD_YES);
+#else
+ MHD_PANIC ("MHD_ELS_EPOLL not supported, should have failed earlier.\n");
+#endif
+ break;
+ }
+ MHD_connection_cleanup_ (daemon);
+ }
+ /* Resume any pending for resume connections, join
+ * all connection's threads (if any) and finally cleanup
+ * everything. */
+ if (! daemon->disallow_suspend_resume)
+ MHD_resume_suspended_connections_ (daemon);
+ MHD_daemon_close_all_connections_ (daemon);
+
+ return (MHD_THRD_RTRN_TYPE_) 0;
+}
+
+
+/**
+ * Setup the thread pool (if needed).
+ *
+ * @param[in,out] daemon daemon to setup thread pool for
+ * @return #MHD_SC_OK on success
+ */
+static enum MHD_StatusCode
+setup_thread_pool (struct MHD_Daemon *daemon)
+{
+ /* Coarse-grained count of connections per thread (note error
+ * due to integer division). Also keep track of how many
+ * connections are leftover after an equal split. */
+ unsigned int conns_per_thread = daemon->global_connection_limit
+ / daemon->threading_mode;
+ unsigned int leftover_conns = daemon->global_connection_limit
+ % daemon->threading_mode;
+ int i;
+ enum MHD_StatusCode sc;
+
+ /* Allocate memory for pooled objects */
+ daemon->worker_pool = MHD_calloc_ (daemon->threading_mode,
+ sizeof (struct MHD_Daemon));
+ if (NULL == daemon->worker_pool)
+ return MHD_SC_THREAD_POOL_MALLOC_FAILURE;
+
+ /* Start the workers in the pool */
+ for (i = 0; i < daemon->threading_mode; i++)
+ {
+ /* Create copy of the Daemon object for each worker */
+ struct MHD_Daemon *d = &daemon->worker_pool[i];
+
+ memcpy (d,
+ daemon,
+ sizeof (struct MHD_Daemon));
+ /* Adjust pooling params for worker daemons; note that memcpy()
+ has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
+ the worker threads. */
+ d->master = daemon;
+ d->worker_pool_size = 0;
+ d->worker_pool = NULL;
+ /* Divide available connections evenly amongst the threads.
+ * Thread indexes in [0, leftover_conns) each get one of the
+ * leftover connections. */
+ d->global_connection_limit = conns_per_thread;
+ if (((unsigned int) i) < leftover_conns)
+ ++d->global_connection_limit;
+
+ if (! daemon->disable_itc)
+ {
+ if (! MHD_itc_init_ (d->itc))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_INITIALIZATION_FAILED,
+ _ (
+ "Failed to create worker inter-thread communication channel: %s\n"),
+ MHD_itc_last_strerror_ () );
+#endif
+ sc = MHD_SC_ITC_INITIALIZATION_FAILED;
+ goto thread_failed;
+ }
+ if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc),
+ NULL)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
+ _ (
+ "File descriptor for inter-thread communication channel exceeds maximum value.\n"));
+#endif
+ MHD_itc_destroy_chk_ (d->itc);
+ sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
+ goto thread_failed;
+ }
+ }
+ else
+ {
+ MHD_itc_set_invalid_ (d->itc);
+ }
+
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) )
+ goto thread_failed;
+#endif
+
+ /* Must init cleanup connection mutex for each worker */
+ if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE,
+ _ ("MHD failed to initialize cleanup connection mutex.\n"));
+#endif
+ if (! daemon->disable_itc)
+ MHD_itc_destroy_chk_ (d->itc);
+ sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE;
+ goto thread_failed;
+ }
+
+ /* Spawn the worker thread */
+ if (! MHD_create_named_thread_ (&d->pid,
+ "MHD-worker",
+ daemon->thread_stack_limit_b,
+ &MHD_polling_thread,
+ d))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_THREAD_POOL_LAUNCH_FAILURE,
+ _ ("Failed to create pool thread: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ /* Free memory for this worker; cleanup below handles
+ * all previously-created workers. */
+ if (! daemon->disable_itc)
+ MHD_itc_destroy_chk_ (d->itc);
+ MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
+ sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE;
+ goto thread_failed;
+ }
+ } /* end for() */
+ return MHD_SC_OK;
+
+thread_failed:
+ /* If no worker threads created, then shut down normally. Calling
+ MHD_stop_daemon (as we do below) doesn't work here since it
+ assumes a 0-sized thread pool means we had been in the default
+ MHD_USE_INTERNAL_POLLING_THREAD mode. */
+ if (0 == i)
+ {
+ if (NULL != daemon->worker_pool)
+ {
+ free (daemon->worker_pool);
+ daemon->worker_pool = NULL;
+ }
+ return MHD_SC_THREAD_LAUNCH_FAILURE;
+ }
+ /* Shutdown worker threads we've already created. Pretend
+ as though we had fully initialized our daemon, but
+ with a smaller number of threads than had been
+ requested. */
+ daemon->worker_pool_size = i;
+ daemon->listen_socket = MHD_daemon_quiesce (daemon);
+ return sc;
+}
+
+
+/**
+ * Start a webserver.
+ *
+ * @param daemon daemon to start; you can no longer set
+ * options on this daemon after this call!
+ * @return #MHD_SC_OK on success
+ * @ingroup event
+ */
+enum MHD_StatusCode
+MHD_daemon_start (struct MHD_Daemon *daemon)
+{
+ enum MHD_StatusCode sc;
+
+ if (MHD_ELS_AUTO == daemon->event_loop_syscall)
+ {
+#if EPOLL_SUPPORT
+ /* We do not support thread-per-connection in combination
+ with epoll, so use poll in this case, otherwise prefer
+ epoll. */
+ if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
+ daemon->event_loop_syscall = MHD_ELS_POLL;
+ else
+ daemon->event_loop_syscall = MHD_ELS_EPOLL;
+#elif HAVE_POLL
+ daemon->event_loop_syscall = MHD_ELS_POLL;
+#else
+ daemon->event_loop_syscall = MHD_ELS_SELECT;
+#endif
+ }
+
+#ifdef EPOLL_SUPPORT
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (0 == daemon->worker_pool_size) &&
+ (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID,
+ _ (
+ "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
+#endif
+ return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID;
+ }
+#endif
+
+ /* Setup ITC */
+ if ( (! daemon->disable_itc) &&
+ (0 == daemon->worker_pool_size) )
+ {
+ if (! MHD_itc_init_ (daemon->itc))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_INITIALIZATION_FAILED,
+ _ ("Failed to create inter-thread communication channel: %s\n"),
+ MHD_itc_last_strerror_ ());
+#endif
+ return MHD_SC_ITC_INITIALIZATION_FAILED;
+ }
+ if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc),
+ NULL)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
+ _ (
+ "File descriptor for inter-thread communication channel exceeds maximum value.\n"));
+#endif
+ return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
+ }
+ }
+
+ if (MHD_SC_OK != (sc = open_listen_socket (daemon)))
+ return sc;
+
+ /* Check listen socket is in range (if we are limited) */
+ if ( (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (daemon->listen_socket,
+ NULL)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_SOCKET_TOO_LARGE,
+ _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
+ daemon->listen_socket,
+ FD_SETSIZE);
+#endif
+ return MHD_SC_LISTEN_SOCKET_TOO_LARGE;
+ }
+
+ /* set listen socket to non-blocking */
+ if ( (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (! MHD_socket_nonblocking_ (daemon->listen_socket)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE,
+ _ ("Failed to set nonblocking mode on listening socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) ||
+ (daemon->worker_pool_size > 0) )
+ {
+ /* Accept must be non-blocking. Multiple children may wake
+ * up to handle a new connection, but only one will win the
+ * race. The others must immediately return. As this is
+ * not possible, we must fail hard here. */
+ return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE;
+ }
+ }
+
+#ifdef EPOLL_SUPPORT
+ /* Setup epoll */
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
+ (0 == daemon->worker_pool_size) &&
+ (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (MHD_SC_OK != (sc = setup_epoll_to_listen (daemon))) )
+ return sc;
+#endif
+
+ /* Setup main listen thread (only if we have no thread pool or
+ external event loop and do have a listen socket) */
+ /* FIXME: why no worker thread if we have no listen socket? */
+ if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ||
+ (1 == daemon->threading_mode) ) &&
+ (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (! MHD_create_named_thread_ (&daemon->pid,
+ (MHD_TM_THREAD_PER_CONNECTION ==
+ daemon->threading_mode)
+ ? "MHD-listen"
+ : "MHD-single",
+ daemon->thread_stack_limit_b,
+ &MHD_polling_thread,
+ daemon) ) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_THREAD_MAIN_LAUNCH_FAILURE,
+ _ ("Failed to create listen thread: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE;
+ }
+
+ /* Setup worker threads */
+ /* FIXME: why no thread pool if we have no listen socket? */
+ if ( (1 < daemon->threading_mode) &&
+ (MHD_INVALID_SOCKET != daemon->listen_socket) &&
+ (MHD_SC_OK != (sc = setup_thread_pool (daemon))) )
+ return sc;
+
+ /* make sure we know our listen port (if any) */
+ get_listen_port_number (daemon);
+
+ return MHD_SC_OK;
+}
+
+
+/* end of daemon_start.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/init.c
^
|
@@ -0,0 +1,149 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/init.c
+ * @brief initialization routines
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "init.h"
+
+
+#ifndef _AUTOINIT_FUNCS_ARE_SUPPORTED
+/**
+ * Track global initialisation
+ */
+volatile unsigned int global_init_count = 0;
+
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+/**
+ * Global initialisation mutex
+ */
+MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+
+#endif
+
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+/**
+ * Track initialization of winsock
+ */
+static int mhd_winsock_inited_ = 0;
+#endif
+
+/**
+ * Default implementation of the panic function,
+ * prints an error message and aborts.
+ *
+ * @param cls unused
+ * @param file name of the file with the problem
+ * @param line line number with the problem
+ * @param reason error message with details
+ */
+static void
+mhd_panic_std (void *cls,
+ const char *file,
+ unsigned int line,
+ const char *reason)
+{
+ (void) cls; /* Mute compiler warning. */
+#ifdef HAVE_MESSAGES
+ fprintf (stderr,
+ _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
+ file,
+ line,
+ reason);
+#else /* ! HAVE_MESSAGES */
+ (void) file; /* Mute compiler warning. */
+ (void) line; /* Mute compiler warning. */
+ (void) reason; /* Mute compiler warning. */
+#endif
+ abort ();
+}
+
+
+/**
+ * Globally initialize library.
+ */
+void
+MHD_init (void)
+{
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ WSADATA wsd;
+#endif /* _WIN32 && ! __CYGWIN__ */
+
+ if (NULL == mhd_panic)
+ mhd_panic = &mhd_panic_std;
+
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ if (0 != WSAStartup (MAKEWORD (2, 2),
+ &wsd))
+ MHD_PANIC (_ ("Failed to initialize winsock.\n"));
+ mhd_winsock_inited_ = 1;
+ if ( (2 != LOBYTE (wsd.wVersion)) &&
+ (2 != HIBYTE (wsd.wVersion)) )
+ MHD_PANIC (_ ("Winsock version 2.2 is not available.\n"));
+#endif
+ MHD_monotonic_sec_counter_init ();
+#ifdef HAVE_FREEBSD_SENDFILE
+ MHD_conn_init_static_ ();
+#endif /* HAVE_FREEBSD_SENDFILE */
+}
+
+
+/**
+ * Global teardown work.
+ */
+void
+MHD_fini (void)
+{
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ if (mhd_winsock_inited_)
+ WSACleanup ();
+#endif
+ MHD_monotonic_sec_counter_finish ();
+}
+
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+
+_SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini);
+
+#else
+
+/**
+ * Check whether global initialisation was performed
+ * and call initialiser if necessary.
+ */
+void
+MHD_check_global_init_ (void)
+{
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_lock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+ if (0 == global_init_count++)
+ MHD_init ();
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_unlock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+}
+
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/init.h
^
|
@@ -0,0 +1,46 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/init.h
+ * @brief functions to initialize library
+ * @author Christian Grothoff
+ */
+#ifndef INIT_H
+#define INIT_H
+
+#include "internal.h"
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+/**
+ * Do nothing - global initialisation is
+ * performed by library constructor.
+ */
+#define MHD_check_global_init_() (void) 0
+#else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+/**
+ * Check whether global initialisation was performed
+ * and call initialiser if necessary.
+ */
+void
+MHD_check_global_init_ (void);
+
+#endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+
+
+#endif /* INIT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/internal.c
^
|
@@ -0,0 +1,288 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/internal.c
+ * @brief internal shared structures
+ * @author Daniel Pittman
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "mhd_str.h"
+
+#ifdef HAVE_MESSAGES
+#if DEBUG_STATES
+/**
+ * State to string dictionary.
+ */
+const char *
+MHD_state_to_string (enum MHD_CONNECTION_STATE state)
+{
+ switch (state)
+ {
+ case MHD_CONNECTION_INIT:
+ return "connection init";
+ case MHD_CONNECTION_URL_RECEIVED:
+ return "connection url received";
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ return "header partially received";
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ return "headers received";
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ return "headers processed";
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ return "continue sending";
+ case MHD_CONNECTION_CONTINUE_SENT:
+ return "continue sent";
+ case MHD_CONNECTION_BODY_RECEIVED:
+ return "body received";
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ return "footer partially received";
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ return "footers received";
+ case MHD_CONNECTION_HEADERS_SENDING:
+ return "headers sending";
+ case MHD_CONNECTION_HEADERS_SENT:
+ return "headers sent";
+ case MHD_CONNECTION_NORMAL_BODY_READY:
+ return "normal body ready";
+ case MHD_CONNECTION_NORMAL_BODY_UNREADY:
+ return "normal body unready";
+ case MHD_CONNECTION_CHUNKED_BODY_READY:
+ return "chunked body ready";
+ case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
+ return "chunked body unready";
+ case MHD_CONNECTION_BODY_SENT:
+ return "body sent";
+ case MHD_CONNECTION_FOOTERS_SENDING:
+ return "footers sending";
+ case MHD_CONNECTION_FOOTERS_SENT:
+ return "footers sent";
+ case MHD_CONNECTION_CLOSED:
+ return "closed";
+ default:
+ return "unrecognized connection state";
+ }
+}
+
+
+#endif
+#endif
+
+
+#ifdef HAVE_MESSAGES
+/**
+ * fprintf-like helper function for logging debug
+ * messages.
+ */
+void
+MHD_DLOG (const struct MHD_Daemon *daemon,
+ enum MHD_StatusCode sc,
+ const char *format,
+ ...)
+{
+ va_list va;
+
+ if (NULL == daemon->logger)
+ return;
+ va_start (va,
+ format);
+ daemon->logger (daemon->logger_cls,
+ sc,
+ format,
+ va);
+ va_end (va);
+}
+
+
+#endif
+
+
+/**
+ * Convert all occurrences of '+' to ' '.
+ *
+ * @param arg string that is modified (in place), must be 0-terminated
+ */
+void
+MHD_unescape_plus (char *arg)
+{
+ char *p;
+
+ for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
+ *p = ' ';
+}
+
+
+/**
+ * Process escape sequences ('%HH') Updates val in place; the
+ * result should be UTF-8 encoded and cannot be larger than the input.
+ * The result must also still be 0-terminated.
+ *
+ * @param val value to unescape (modified in the process)
+ * @return length of the resulting val (strlen(val) maybe
+ * shorter afterwards due to elimination of escape sequences)
+ */
+size_t
+MHD_http_unescape (char *val)
+{
+ char *rpos = val;
+ char *wpos = val;
+
+ while ('\0' != *rpos)
+ {
+ uint32_t num;
+ switch (*rpos)
+ {
+ case '%':
+ if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
+ 2,
+ &num))
+ {
+ *wpos = (char) ((unsigned char) num);
+ wpos++;
+ rpos += 3;
+ break;
+ }
+ /* TODO: add bad sequence handling */
+ /* intentional fall through! */
+ default:
+ *wpos = *rpos;
+ wpos++;
+ rpos++;
+ }
+ }
+ *wpos = '\0'; /* add 0-terminator */
+ return wpos - val; /* = strlen(val) */
+}
+
+
+/**
+ * Parse and unescape the arguments given by the client
+ * as part of the HTTP request URI.
+ *
+ * @param request request to add headers to
+ * @param kind header kind to pass to @a cb
+ * @param[in,out] args argument URI string (after "?" in URI),
+ * clobbered in the process!
+ * @param cb function to call on each key-value pair found
+ * @param[out] num_headers set to the number of headers found
+ * @return false on failure (@a cb returned false),
+ * true for success (parsing succeeded, @a cb always
+ * returned true)
+ */
+bool
+MHD_parse_arguments_ (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ char *args,
+ MHD_ArgumentIterator_ cb,
+ unsigned int *num_headers)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+ char *equals;
+ char *amper;
+
+ *num_headers = 0;
+ while ( (NULL != args) &&
+ ('\0' != args[0]) )
+ {
+ equals = strchr (args, '=');
+ amper = strchr (args, '&');
+ if (NULL == amper)
+ {
+ /* last argument */
+ if (NULL == equals)
+ {
+ /* last argument, without '=' */
+ MHD_unescape_plus (args);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ args);
+ if (! cb (request,
+ args,
+ NULL,
+ kind))
+ return false;
+ (*num_headers)++;
+ break;
+ }
+ /* got 'foo=bar' */
+ equals[0] = '\0';
+ equals++;
+ MHD_unescape_plus (args);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ args);
+ MHD_unescape_plus (equals);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ equals);
+ if (! cb (request,
+ args,
+ equals,
+ kind))
+ return false;
+ (*num_headers)++;
+ break;
+ }
+ /* amper is non-NULL here */
+ amper[0] = '\0';
+ amper++;
+ if ( (NULL == equals) ||
+ (equals >= amper) )
+ {
+ /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
+ MHD_unescape_plus (args);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ args);
+ if (! cb (request,
+ args,
+ NULL,
+ kind))
+ return false;
+ /* continue with 'bar' */
+ (*num_headers)++;
+ args = amper;
+ continue;
+ }
+ /* equals and amper are non-NULL here, and equals < amper,
+ so we got regular 'foo=value&bar...'-kind of argument */
+ equals[0] = '\0';
+ equals++;
+ MHD_unescape_plus (args);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ args);
+ MHD_unescape_plus (equals);
+ daemon->unescape_cb (daemon->unescape_cb_cls,
+ request,
+ equals);
+ if (! cb (request,
+ args,
+ equals,
+ kind))
+ return false;
+ (*num_headers)++;
+ args = amper;
+ }
+ return true;
+}
+
+
+/* end of internal.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/internal.h
^
|
@@ -0,0 +1,1892 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/internal.h
+ * @brief internal shared structures
+ * @author Daniel Pittman
+ * @author Christian Grothoff
+ */
+
+#ifndef INTERNAL_H
+#define INTERNAL_H
+
+#include "mhd_options.h"
+#include "platform.h"
+#include "microhttpd2.h"
+#include "microhttpd_tls.h"
+#include "mhd_assert.h"
+#include "mhd_compat.h"
+#include "mhd_itc.h"
+#include "mhd_mono_clock.h"
+#include "memorypool.h"
+
+#ifdef HTTPS_SUPPORT
+#include <gnutls/gnutls.h>
+#if GNUTLS_VERSION_MAJOR >= 3
+#include <gnutls/abstract.h>
+#endif
+#endif /* HTTPS_SUPPORT */
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
+#ifdef MHD_PANIC
+/* Override any defined MHD_PANIC macro with proper one */
+#undef MHD_PANIC
+#endif /* MHD_PANIC */
+
+#ifdef HAVE_MESSAGES
+/**
+ * Trigger 'panic' action based on fatal errors.
+ *
+ * @param msg error message (const char *)
+ */
+#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); \
+ BUILTIN_NOT_REACHED; } while (0)
+#else
+/**
+ * Trigger 'panic' action based on fatal errors.
+ *
+ * @param msg error message (const char *)
+ */
+#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); \
+ BUILTIN_NOT_REACHED; } while (0)
+#endif
+
+#include "mhd_threads.h"
+#include "mhd_locks.h"
+#include "mhd_sockets.h"
+#include "mhd_str.h"
+#include "mhd_itc_types.h"
+
+
+#ifdef HAVE_MESSAGES
+/**
+ * fprintf()-like helper function for logging debug
+ * messages.
+ */
+void
+MHD_DLOG (const struct MHD_Daemon *daemon,
+ enum MHD_StatusCode sc,
+ const char *format,
+ ...);
+
+#endif
+
+
+/**
+ * Close FD and abort execution if error is detected.
+ * @param fd the FD to close
+ */
+#define MHD_fd_close_chk_(fd) do { \
+ if ( (0 != close ((fd)) && (EBADF == errno)) ) \
+ MHD_PANIC (_ ("Failed to close FD.\n")); \
+} while (0)
+
+/**
+ * Should we perform additional sanity checks at runtime (on our internal
+ * invariants)? This may lead to aborts, but can be useful for debugging.
+ */
+#define EXTRA_CHECKS MHD_NO
+
+#define MHD_MAX(a,b) (((a)<(b)) ? (b) : (a))
+#define MHD_MIN(a,b) (((a)<(b)) ? (a) : (b))
+
+
+/**
+ * Minimum size by which MHD tries to increment read/write buffers.
+ * We usually begin with half the available pool space for the
+ * IO-buffer, but if absolutely needed we additively grow by the
+ * number of bytes given here (up to -- theoretically -- the full pool
+ * space).
+ */
+#define MHD_BUF_INC_SIZE 1024
+
+
+/**
+ * Handler for fatal errors.
+ */
+extern MHD_PanicCallback mhd_panic;
+
+/**
+ * Closure argument for "mhd_panic".
+ */
+extern void *mhd_panic_cls;
+
+/* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */
+#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= \
+ 5)
+#define BUILTIN_NOT_REACHED __builtin_unreachable ()
+#elif defined(_MSC_FULL_VER)
+#define BUILTIN_NOT_REACHED __assume (0)
+#else
+#define BUILTIN_NOT_REACHED
+#endif
+
+#ifndef MHD_STATICSTR_LEN_
+/**
+ * Determine length of static string / macro strings at compile time.
+ */
+#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
+#endif /* ! MHD_STATICSTR_LEN_ */
+
+
+/**
+ * Ability to use same connection for next request
+ */
+enum MHD_ConnKeepAlive
+{
+ /**
+ * Connection must be closed after sending response.
+ */
+ MHD_CONN_MUST_CLOSE = -1,
+
+ /**
+ * KeelAlive state is not yet determined
+ */
+ MHD_CONN_KEEPALIVE_UNKOWN = 0,
+
+ /**
+ * Connection can be used for serving next request
+ */
+ MHD_CONN_USE_KEEPALIVE = 1
+};
+
+
+/**
+ * Function to receive plaintext data.
+ *
+ * @param conn the connection struct
+ * @param write_to where to write received data
+ * @param max_bytes maximum number of bytes to receive
+ * @return number of bytes written to @a write_to
+ */
+typedef ssize_t
+(*ReceiveCallback) (struct MHD_Connection *conn,
+ void *write_to,
+ size_t max_bytes);
+
+
+/**
+ * Function to transmit plaintext data.
+ *
+ * @param conn the connection struct
+ * @param read_from where to read data to transmit
+ * @param max_bytes maximum number of bytes to transmit
+ * @return number of bytes transmitted
+ */
+typedef ssize_t
+(*TransmitCallback) (struct MHD_Connection *conn,
+ const void *read_from,
+ size_t max_bytes);
+
+
+/**
+ * States in a state machine for a request.
+ *
+ * The main transitions are any-state to #MHD_REQUEST_CLOSED, any
+ * state to state+1, #MHD_REQUEST_FOOTERS_SENT to
+ * #MHD_REQUEST_INIT. #MHD_REQUEST_CLOSED is the terminal state
+ * and #MHD_REQUEST_INIT the initial state.
+ *
+ * Note that transitions for *reading* happen only after the input has
+ * been processed; transitions for *writing* happen after the
+ * respective data has been put into the write buffer (the write does
+ * not have to be completed yet). A transition to
+ * #MHD_REQUEST_CLOSED or #MHD_REQUEST_INIT requires the write
+ * to be complete.
+ */
+enum MHD_REQUEST_STATE // FIXME: fix capitalization!
+{
+ /**
+ * Request just started (no headers received).
+ * Waiting for the line with the request type, URL and version.
+ */
+ MHD_REQUEST_INIT = 0,
+
+ /**
+ * 1: We got the URL (and request type and version). Wait for a header line.
+ */
+ MHD_REQUEST_URL_RECEIVED = MHD_REQUEST_INIT + 1,
+
+ /**
+ * 2: We got part of a multi-line request header. Wait for the rest.
+ */
+ MHD_REQUEST_HEADER_PART_RECEIVED = MHD_REQUEST_URL_RECEIVED + 1,
+
+ /**
+ * 3: We got the request headers. Process them.
+ */
+ MHD_REQUEST_HEADERS_RECEIVED = MHD_REQUEST_HEADER_PART_RECEIVED + 1,
+
+ /**
+ * 4: We have processed the request headers. Send 100 continue.
+ */
+ MHD_REQUEST_HEADERS_PROCESSED = MHD_REQUEST_HEADERS_RECEIVED + 1,
+
+ /**
+ * 5: We have processed the headers and need to send 100 CONTINUE.
+ */
+ MHD_REQUEST_CONTINUE_SENDING = MHD_REQUEST_HEADERS_PROCESSED + 1,
+
+ /**
+ * 6: We have sent 100 CONTINUE (or do not need to). Read the message body.
+ */
+ MHD_REQUEST_CONTINUE_SENT = MHD_REQUEST_CONTINUE_SENDING + 1,
+
+ /**
+ * 7: We got the request body. Wait for a line of the footer.
+ */
+ MHD_REQUEST_BODY_RECEIVED = MHD_REQUEST_CONTINUE_SENT + 1,
+
+ /**
+ * 8: We got part of a line of the footer. Wait for the
+ * rest.
+ */
+ MHD_REQUEST_FOOTER_PART_RECEIVED = MHD_REQUEST_BODY_RECEIVED + 1,
+
+ /**
+ * 9: We received the entire footer. Wait for a response to be queued
+ * and prepare the response headers.
+ */
+ MHD_REQUEST_FOOTERS_RECEIVED = MHD_REQUEST_FOOTER_PART_RECEIVED + 1,
+
+ /**
+ * 10: We have prepared the response headers in the writ buffer.
+ * Send the response headers.
+ */
+ MHD_REQUEST_HEADERS_SENDING = MHD_REQUEST_FOOTERS_RECEIVED + 1,
+
+ /**
+ * 11: We have sent the response headers. Get ready to send the body.
+ */
+ MHD_REQUEST_HEADERS_SENT = MHD_REQUEST_HEADERS_SENDING + 1,
+
+ /**
+ * 12: We are ready to send a part of a non-chunked body. Send it.
+ */
+ MHD_REQUEST_NORMAL_BODY_READY = MHD_REQUEST_HEADERS_SENT + 1,
+
+ /**
+ * 13: We are waiting for the client to provide more
+ * data of a non-chunked body.
+ */
+ MHD_REQUEST_NORMAL_BODY_UNREADY = MHD_REQUEST_NORMAL_BODY_READY + 1,
+
+ /**
+ * 14: We are ready to send a chunk.
+ */
+ MHD_REQUEST_CHUNKED_BODY_READY = MHD_REQUEST_NORMAL_BODY_UNREADY + 1,
+
+ /**
+ * 15: We are waiting for the client to provide a chunk of the body.
+ */
+ MHD_REQUEST_CHUNKED_BODY_UNREADY = MHD_REQUEST_CHUNKED_BODY_READY + 1,
+
+ /**
+ * 16: We have sent the response body. Prepare the footers.
+ */
+ MHD_REQUEST_BODY_SENT = MHD_REQUEST_CHUNKED_BODY_UNREADY + 1,
+
+ /**
+ * 17: We have prepared the response footer. Send it.
+ */
+ MHD_REQUEST_FOOTERS_SENDING = MHD_REQUEST_BODY_SENT + 1,
+
+ /**
+ * 18: We have sent the response footer. Shutdown or restart.
+ */
+ MHD_REQUEST_FOOTERS_SENT = MHD_REQUEST_FOOTERS_SENDING + 1,
+
+ /**
+ * 19: This request is to be closed.
+ */
+ MHD_REQUEST_CLOSED = MHD_REQUEST_FOOTERS_SENT + 1,
+
+#ifdef UPGRADE_SUPPORT
+ /**
+ * Request was "upgraded" and socket is now under the
+ * control of the application.
+ */
+ MHD_REQUEST_UPGRADE
+#endif /* UPGRADE_SUPPORT */
+
+};
+
+
+/**
+ * Header or cookie in HTTP request or response.
+ */
+struct MHD_HTTP_Header
+{
+ /**
+ * Headers are kept in a linked list.
+ */
+ struct MHD_HTTP_Header *next;
+
+ /**
+ * The name of the header (key), without the colon.
+ */
+ char *header;
+
+ /**
+ * The value of the header.
+ */
+ char *value;
+
+ /**
+ * Type of the header (where in the HTTP protocol is this header
+ * from).
+ */
+ enum MHD_ValueKind kind;
+
+};
+
+
+/**
+ * State kept for each HTTP request.
+ */
+struct MHD_Request
+{
+
+ /**
+ * Reference to the `struct MHD_Daemon`.
+ */
+ struct MHD_Daemon *daemon;
+
+ /**
+ * Connection this request is associated with.
+ */
+ struct MHD_Connection *connection;
+
+ /**
+ * Response to return for this request, set once
+ * it is available.
+ */
+ struct MHD_Response *response;
+
+ /**
+ * Linked list of parsed headers.
+ */
+ struct MHD_HTTP_Header *headers_received;
+
+ /**
+ * Tail of linked list of parsed headers.
+ */
+ struct MHD_HTTP_Header *headers_received_tail;
+
+ /**
+ * We allow the main application to associate some pointer with the
+ * HTTP request, which is passed to each #MHD_AccessHandlerCallback
+ * and some other API calls. Here is where we store it. (MHD does
+ * not know or care what it is).
+ */
+ void *client_context;
+
+ /**
+ * Request method as string. Should be GET/POST/etc. Allocated in
+ * pool.
+ */
+ char *method_s;
+
+ /**
+ * Requested URL (everything after "GET" only). Allocated
+ * in pool.
+ */
+ const char *url;
+
+ /**
+ * HTTP version string (i.e. http/1.1). Allocated
+ * in pool.
+ */
+ char *version_s;
+
+ /**
+ * Close connection after sending response?
+ * Functions may change value from "Unknown" or "KeepAlive" to "Must close",
+ * but no functions reset value "Must Close" to any other value.
+ */
+ enum MHD_ConnKeepAlive keepalive;
+
+ /**
+ * Buffer for reading requests. Allocated in pool. Actually one
+ * byte larger than @e read_buffer_size (if non-NULL) to allow for
+ * 0-termination.
+ */
+ char *read_buffer;
+
+ /**
+ * Buffer for writing response (headers only). Allocated
+ * in pool.
+ */
+ char *write_buffer;
+
+ /**
+ * Last incomplete header line during parsing of headers.
+ * Allocated in pool. Only valid if state is
+ * either #MHD_REQUEST_HEADER_PART_RECEIVED or
+ * #MHD_REQUEST_FOOTER_PART_RECEIVED.
+ */
+ char *last;
+
+ /**
+ * Position after the colon on the last incomplete header
+ * line during parsing of headers.
+ * Allocated in pool. Only valid if state is
+ * either #MHD_REQUEST_HEADER_PART_RECEIVED or
+ * #MHD_REQUEST_FOOTER_PART_RECEIVED.
+ */
+ char *colon;
+
+#ifdef UPGRADE_SUPPORT
+ /**
+ * If this connection was upgraded, this points to
+ * the upgrade response details such that the
+ * #thread_main_connection_upgrade()-logic can perform the
+ * bi-directional forwarding.
+ */
+ struct MHD_UpgradeResponseHandle *urh;
+#endif /* UPGRADE_SUPPORT */
+
+ /**
+ * Size of @e read_buffer (in bytes). This value indicates
+ * how many bytes we're willing to read into the buffer;
+ * the real buffer is one byte longer to allow for
+ * adding zero-termination (when needed).
+ */
+ size_t read_buffer_size;
+
+ /**
+ * Position where we currently append data in
+ * @e read_buffer (last valid position).
+ */
+ size_t read_buffer_offset;
+
+ /**
+ * Size of @e write_buffer (in bytes).
+ */
+ size_t write_buffer_size;
+
+ /**
+ * Offset where we are with sending from @e write_buffer.
+ */
+ size_t write_buffer_send_offset;
+
+ /**
+ * Last valid location in write_buffer (where do we
+ * append and up to where is it safe to send?)
+ */
+ size_t write_buffer_append_offset;
+
+ /**
+ * Number of bytes we had in the HTTP header, set once we
+ * pass #MHD_REQUEST_HEADERS_RECEIVED.
+ */
+ size_t header_size;
+
+ /**
+ * How many more bytes of the body do we expect
+ * to read? #MHD_SIZE_UNKNOWN for unknown.
+ */
+ uint64_t remaining_upload_size;
+
+ /**
+ * If we are receiving with chunked encoding, where are we right
+ * now? Set to 0 if we are waiting to receive the chunk size;
+ * otherwise, this is the size of the current chunk. A value of
+ * zero is also used when we're at the end of the chunks.
+ */
+ uint64_t current_chunk_size;
+
+ /**
+ * If we are receiving with chunked encoding, where are we currently
+ * with respect to the current chunk (at what offset / position)?
+ */
+ uint64_t current_chunk_offset;
+
+ /**
+ * Current write position in the actual response
+ * (excluding headers, content only; should be 0
+ * while sending headers).
+ */
+ uint64_t response_write_position;
+
+ #if defined(_MHD_HAVE_SENDFILE)
+ // FIXME: document, fix capitalization!
+ enum MHD_resp_sender_
+ {
+ MHD_resp_sender_std = 0,
+ MHD_resp_sender_sendfile
+ } resp_sender;
+#endif /* _MHD_HAVE_SENDFILE */
+
+ /**
+ * Position in the 100 CONTINUE message that
+ * we need to send when receiving http 1.1 requests.
+ */
+ size_t continue_message_write_offset;
+
+ /**
+ * State in the FSM for this request.
+ */
+ enum MHD_REQUEST_STATE state;
+
+ /**
+ * HTTP method, as an enum.
+ */
+ enum MHD_Method method;
+
+ /**
+ * What is this request waiting for?
+ */
+ enum MHD_RequestEventLoopInfo event_loop_info;
+
+ /**
+ * Are we currently inside the "idle" handler (to avoid recursively
+ * invoking it).
+ */
+ bool in_idle;
+
+ /**
+ * Are we currently inside the "idle" handler (to avoid recursively
+ * invoking it).
+ */
+ bool in_cleanup;
+
+ /**
+ * Are we receiving with chunked encoding? This will be set to
+ * #MHD_YES after we parse the headers and are processing the body
+ * with chunks. After we are done with the body and we are
+ * processing the footers; once the footers are also done, this will
+ * be set to #MHD_NO again (before the final call to the handler).
+ */
+ bool have_chunked_upload;
+};
+
+
+/**
+ * State of the socket with respect to epoll (bitmask).
+ */
+enum MHD_EpollState
+{
+
+ /**
+ * The socket is not involved with a defined state in epoll() right
+ * now.
+ */
+ MHD_EPOLL_STATE_UNREADY = 0,
+
+ /**
+ * epoll() told us that data was ready for reading, and we did
+ * not consume all of it yet.
+ */
+ MHD_EPOLL_STATE_READ_READY = 1,
+
+ /**
+ * epoll() told us that space was available for writing, and we did
+ * not consume all of it yet.
+ */
+ MHD_EPOLL_STATE_WRITE_READY = 2,
+
+ /**
+ * Is this connection currently in the 'eready' EDLL?
+ */
+ MHD_EPOLL_STATE_IN_EREADY_EDLL = 4,
+
+ /**
+ * Is this connection currently in the epoll() set?
+ */
+ MHD_EPOLL_STATE_IN_EPOLL_SET = 8,
+
+ /**
+ * Is this connection currently suspended?
+ */
+ MHD_EPOLL_STATE_SUSPENDED = 16,
+
+ /**
+ * Is this connection in some error state?
+ */
+ MHD_EPOLL_STATE_ERROR = 128
+};
+
+
+/**
+ * State kept per HTTP connection.
+ */
+struct MHD_Connection
+{
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * Next pointer for the EDLL listing connections that are epoll-ready.
+ */
+ struct MHD_Connection *nextE;
+
+ /**
+ * Previous pointer for the EDLL listing connections that are epoll-ready.
+ */
+ struct MHD_Connection *prevE;
+#endif
+
+ /**
+ * Next pointer for the DLL describing our IO state.
+ */
+ struct MHD_Connection *next;
+
+ /**
+ * Previous pointer for the DLL describing our IO state.
+ */
+ struct MHD_Connection *prev;
+
+ /**
+ * Next pointer for the XDLL organizing connections by timeout.
+ * This DLL can be either the
+ * 'manual_timeout_head/manual_timeout_tail' or the
+ * 'normal_timeout_head/normal_timeout_tail', depending on whether a
+ * custom timeout is set for the connection.
+ */
+ struct MHD_Connection *nextX;
+
+ /**
+ * Previous pointer for the XDLL organizing connections by timeout.
+ */
+ struct MHD_Connection *prevX;
+
+ /**
+ * Reference to the MHD_Daemon struct.
+ */
+ struct MHD_Daemon *daemon;
+
+ /**
+ * The memory pool is created whenever we first read from the TCP
+ * stream and destroyed at the end of each request (and re-created
+ * for the next request). In the meantime, this pointer is NULL.
+ * The pool is used for all request-related data except for the
+ * response (which maybe shared between requests) and the IP
+ * address (which persists across individual requests).
+ */
+ struct MemoryPool *pool;
+
+ /**
+ * We allow the main application to associate some pointer with the
+ * TCP connection (which may span multiple HTTP requests). Here is
+ * where we store it. (MHD does not know or care what it is).
+ * The location is given to the #MHD_NotifyConnectionCallback and
+ * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+ */
+ void *socket_context;
+
+#ifdef HTTPS_SUPPORT
+ /**
+ * State kept per TLS connection. Plugin-specific.
+ */
+ struct MHD_TLS_ConnectionState *tls_cs;
+#endif
+
+ /**
+ * Function used for reading HTTP request stream.
+ */
+ ReceiveCallback recv_cls;
+
+ /**
+ * Function used for writing HTTP response stream.
+ */
+ TransmitCallback send_cls;
+
+ /**
+ * Information about the current request we are processing
+ * on this connection.
+ */
+ struct MHD_Request request;
+
+ /**
+ * Thread handle for this connection (if we are using
+ * one thread per connection).
+ */
+ MHD_thread_handle_ID_ pid;
+
+ /**
+ * Foreign address (of length @e addr_len).
+ */
+ struct sockaddr_storage addr;
+
+ /**
+ * Length of the foreign address.
+ */
+ socklen_t addr_len;
+
+ /**
+ * Last time this connection had any activity
+ * (reading or writing).
+ */
+ time_t last_activity;
+
+ /**
+ * After how many seconds of inactivity should
+ * this connection time out? Zero for no timeout.
+ */
+ time_t connection_timeout;
+
+ /**
+ * Socket for this connection. Set to #MHD_INVALID_SOCKET if
+ * this connection has died (daemon should clean
+ * up in that case).
+ */
+ MHD_socket socket_fd;
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * What is the state of this socket in relation to epoll?
+ */
+ enum MHD_EpollState epoll_state;
+#endif
+
+ /**
+ * Is the connection suspended?
+ */
+ bool suspended;
+
+ /**
+ * Are we ready to read from TLS for this connection?
+ */
+ bool tls_read_ready;
+
+ /**
+ * Is the connection wanting to resume?
+ */
+ bool resuming;
+
+ /**
+ * Set to `true` if the thread has been joined.
+ */
+ bool thread_joined;
+
+ /**
+ * true if #socket_fd is non-blocking, false otherwise.
+ */
+ bool sk_nonblck;
+
+ /**
+ * Has this socket been closed for reading (i.e. other side closed
+ * the connection)? If so, we must completely close the connection
+ * once we are done sending our response (and stop trying to read
+ * from this socket).
+ */
+ bool read_closed;
+
+};
+
+
+#ifdef UPGRADE_SUPPORT
+/**
+ * Buffer we use for upgrade response handling in the unlikely
+ * case where the memory pool was so small it had no buffer
+ * capacity left. Note that we don't expect to _ever_ use this
+ * buffer, so it's mostly wasted memory (except that it allows
+ * us to handle a tricky error condition nicely). So no need to
+ * make this one big. Applications that want to perform well
+ * should just pick an adequate size for the memory pools.
+ */
+#define RESERVE_EBUF_SIZE 8
+
+/**
+ * Context we pass to epoll() for each of the two sockets
+ * of a `struct MHD_UpgradeResponseHandle`. We need to do
+ * this so we can distinguish the two sockets when epoll()
+ * gives us event notifications.
+ */
+struct UpgradeEpollHandle
+{
+ /**
+ * Reference to the overall response handle this struct is
+ * included within.
+ */
+ struct MHD_UpgradeResponseHandle *urh;
+
+ /**
+ * The socket this event is kind-of about. Note that this is NOT
+ * necessarily the socket we are polling on, as for when we read
+ * from TLS, we epoll() on the connection's socket
+ * (`urh->connection->socket_fd`), while this then the application's
+ * socket (where the application will read from). Nevertheless, for
+ * the application to read, we need to first read from TLS, hence
+ * the two are related.
+ *
+ * Similarly, for writing to TLS, this epoll() will be on the
+ * connection's `socket_fd`, and this will merely be the FD which
+ * the application would write to. Hence this struct must always be
+ * interpreted based on which field in `struct
+ * MHD_UpgradeResponseHandle` it is (`app` or `mhd`).
+ */
+ MHD_socket socket;
+
+ /**
+ * IO-state of the @e socket (or the connection's `socket_fd`).
+ */
+ enum MHD_EpollState celi;
+
+};
+
+
+/**
+ * Handle given to the application to manage special
+ * actions relating to MHD responses that "upgrade"
+ * the HTTP protocol (i.e. to WebSockets).
+ */
+struct MHD_UpgradeResponseHandle
+{
+ /**
+ * The connection for which this is an upgrade handle. Note that
+ * because a response may be shared over many connections, this may
+ * not be the only upgrade handle for the response of this connection.
+ */
+ struct MHD_Connection *connection;
+
+#ifdef HTTPS_SUPPORT
+ /**
+ * Kept in a DLL per daemon.
+ */
+ struct MHD_UpgradeResponseHandle *next;
+
+ /**
+ * Kept in a DLL per daemon.
+ */
+ struct MHD_UpgradeResponseHandle *prev;
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * Next pointer for the EDLL listing urhs that are epoll-ready.
+ */
+ struct MHD_UpgradeResponseHandle *nextE;
+
+ /**
+ * Previous pointer for the EDLL listing urhs that are epoll-ready.
+ */
+ struct MHD_UpgradeResponseHandle *prevE;
+
+ /**
+ * Specifies whether urh already in EDLL list of ready connections.
+ */
+ bool in_eready_list;
+#endif
+
+ /**
+ * The buffer for receiving data from TLS to
+ * be passed to the application. Contains @e in_buffer_size
+ * bytes (unless @e in_buffer_size is zero). Do not free!
+ */
+ char *in_buffer;
+
+ /**
+ * The buffer for receiving data from the application to
+ * be passed to TLS. Contains @e out_buffer_size
+ * bytes (unless @e out_buffer_size is zero). Do not free!
+ */
+ char *out_buffer;
+
+ /**
+ * Size of the @e in_buffer.
+ * Set to 0 if the TLS connection went down for reading or socketpair
+ * went down for writing.
+ */
+ size_t in_buffer_size;
+
+ /**
+ * Size of the @e out_buffer.
+ * Set to 0 if the TLS connection went down for writing or socketpair
+ * went down for reading.
+ */
+ size_t out_buffer_size;
+
+ /**
+ * Number of bytes actually in use in the @e in_buffer. Can be larger
+ * than @e in_buffer_size if and only if @a in_buffer_size is zero and
+ * we still have bytes that can be forwarded.
+ * Reset to zero if all data was forwarded to socketpair or
+ * if socketpair went down for writing.
+ */
+ size_t in_buffer_used;
+
+ /**
+ * Number of bytes actually in use in the @e out_buffer. Can be larger
+ * than @e out_buffer_size if and only if @a out_buffer_size is zero and
+ * we still have bytes that can be forwarded.
+ * Reset to zero if all data was forwarded to TLS connection or
+ * if TLS connection went down for writing.
+ */
+ size_t out_buffer_used;
+
+ /**
+ * The socket we gave to the application (r/w).
+ */
+ struct UpgradeEpollHandle app;
+
+ /**
+ * If @a app_sock was a socketpair, our end of it, otherwise
+ * #MHD_INVALID_SOCKET; (r/w).
+ */
+ struct UpgradeEpollHandle mhd;
+
+ /**
+ * Emergency IO buffer we use in case the memory pool has literally
+ * nothing left.
+ */
+ char e_buf[RESERVE_EBUF_SIZE];
+
+#endif /* HTTPS_SUPPORT */
+
+ /**
+ * Set to true after the application finished with the socket
+ * by #MHD_UPGRADE_ACTION_CLOSE.
+ *
+ * When BOTH @e was_closed (changed by command from application)
+ * AND @e clean_ready (changed internally by MHD) are set to
+ * #MHD_YES, function #MHD_resume_connection() will move this
+ * connection to cleanup list.
+ * @remark This flag could be changed from any thread.
+ */
+ volatile bool was_closed;
+
+ /**
+ * Set to true if connection is ready for cleanup.
+ *
+ * In TLS mode functions #MHD_connection_finish_forward_() must
+ * be called before setting this flag to true.
+ *
+ * In thread-per-connection mode, true in this flag means
+ * that connection's thread exited or about to exit and will
+ * not use MHD_Connection::urh data anymore.
+ *
+ * In any mode true in this flag also means that
+ * MHD_Connection::urh data will not be used for socketpair
+ * forwarding and forwarding itself is finished.
+ *
+ * When BOTH @e was_closed (changed by command from application)
+ * AND @e clean_ready (changed internally by MHD) are set to
+ * true, function #MHD_resume_connection() will move this
+ * connection to cleanup list.
+ * @remark This flag could be changed from thread that process
+ * connection's recv(), send() and response.
+ */
+ bool clean_ready;
+};
+#endif /* UPGRADE_SUPPORT */
+
+
+/**
+ * State kept for each MHD daemon. All connections are kept in two
+ * doubly-linked lists. The first one reflects the state of the
+ * connection in terms of what operations we are waiting for (read,
+ * write, locally blocked, cleanup) whereas the second is about its
+ * timeout state (default or custom).
+ */
+struct MHD_Daemon
+{
+ /**
+ * Function to call to handle incoming requests.
+ */
+ MHD_RequestCallback rc;
+
+ /**
+ * Closure for @e rc.
+ */
+ void *rc_cls;
+
+ /**
+ * Function to call for logging.
+ */
+ MHD_LoggingCallback logger;
+
+ /**
+ * Closure for @e logger.
+ */
+ void *logger_cls;
+
+ /**
+ * Function to call to accept/reject connections based on
+ * the client's IP address.
+ */
+ MHD_AcceptPolicyCallback accept_policy_cb;
+
+ /**
+ * Closure for @e accept_policy_cb.
+ */
+ void *accept_policy_cb_cls;
+
+ /**
+ * Function to call on the full URL early for logging.
+ */
+ MHD_EarlyUriLogCallback early_uri_logger_cb;
+
+ /**
+ * Closure for @e early_uri_logger_cb.
+ */
+ void *early_uri_logger_cb_cls;
+
+ /**
+ * Function to call whenever a connection is started or
+ * closed.
+ */
+ MHD_NotifyConnectionCallback notify_connection_cb;
+
+ /**
+ * Closure for @e notify_connection_cb.
+ */
+ void *notify_connection_cb_cls;
+
+ /**
+ * Function to call to unescape sequences in URIs and URI arguments.
+ * See #MHD_daemon_unescape_cb().
+ */
+ MHD_UnescapeCallback unescape_cb;
+
+ /**
+ * Closure for @e unescape_cb.
+ */
+ void *unescape_cb_cls;
+
+ /**
+ * Pointer to master daemon (NULL if this is the master)
+ */
+ struct MHD_Daemon *master;
+
+ /**
+ * Worker daemons (one per thread)
+ */
+ struct MHD_Daemon *worker_pool;
+
+
+#if HTTPS_SUPPORT
+#ifdef UPGRADE_SUPPORT
+ /**
+ * Head of DLL of upgrade response handles we are processing.
+ * Used for upgraded TLS connections when thread-per-connection
+ * is not used.
+ */
+ struct MHD_UpgradeResponseHandle *urh_head;
+
+ /**
+ * Tail of DLL of upgrade response handles we are processing.
+ * Used for upgraded TLS connections when thread-per-connection
+ * is not used.
+ */
+ struct MHD_UpgradeResponseHandle *urh_tail;
+#endif /* UPGRADE_SUPPORT */
+
+ /**
+ * Which TLS backend should be used. NULL for no TLS.
+ * This is merely the handle to the dlsym() object, not
+ * the API.
+ */
+ void *tls_backend_lib;
+
+ /**
+ * Callback functions to use for TLS operations.
+ */
+ struct MHD_TLS_Plugin *tls_api;
+#endif
+#if ENABLE_DAUTH
+
+ /**
+ * Random values to be used by digest authentication module.
+ * Size given in @e digest_auth_random_buf_size.
+ */
+ const void *digest_auth_random_buf;
+#endif
+
+ /**
+ * Head of the XDLL of ALL connections with a default ('normal')
+ * timeout, sorted by timeout (earliest at the tail, most recently
+ * used connection at the head). MHD can just look at the tail of
+ * this list to determine the timeout for all of its elements;
+ * whenever there is an event of a connection, the connection is
+ * moved back to the tail of the list.
+ *
+ * All connections by default start in this list; if a custom
+ * timeout that does not match @e connection_timeout is set, they
+ * are moved to the @e manual_timeout_head-XDLL.
+ * Not used in MHD_USE_THREAD_PER_CONNECTION mode as each thread
+ * needs only one connection-specific timeout.
+ */
+ struct MHD_Connection *normal_timeout_head;
+
+ /**
+ * Tail of the XDLL of ALL connections with a default timeout,
+ * sorted by timeout (earliest timeout at the tail).
+ * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
+ */
+ struct MHD_Connection *normal_timeout_tail;
+
+ /**
+ * Head of the XDLL of ALL connections with a non-default/custom
+ * timeout, unsorted. MHD will do a O(n) scan over this list to
+ * determine the current timeout.
+ * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
+ */
+ struct MHD_Connection *manual_timeout_head;
+
+ /**
+ * Tail of the XDLL of ALL connections with a non-default/custom
+ * timeout, unsorted.
+ * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
+ */
+ struct MHD_Connection *manual_timeout_tail;
+
+ /**
+ * Head of doubly-linked list of our current, active connections.
+ */
+ struct MHD_Connection *connections_head;
+
+ /**
+ * Tail of doubly-linked list of our current, active connections.
+ */
+ struct MHD_Connection *connections_tail;
+
+ /**
+ * Head of doubly-linked list of our current but suspended
+ * connections.
+ */
+ struct MHD_Connection *suspended_connections_head;
+
+ /**
+ * Tail of doubly-linked list of our current but suspended
+ * connections.
+ */
+ struct MHD_Connection *suspended_connections_tail;
+
+ /**
+ * Head of doubly-linked list of connections to clean up.
+ */
+ struct MHD_Connection *cleanup_head;
+
+ /**
+ * Tail of doubly-linked list of connections to clean up.
+ */
+ struct MHD_Connection *cleanup_tail;
+
+ /**
+ * Table storing number of connections per IP
+ */
+ void *per_ip_connection_count;
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * Head of EDLL of connections ready for processing (in epoll mode).
+ */
+ struct MHD_Connection *eready_head;
+
+ /**
+ * Tail of EDLL of connections ready for processing (in epoll mode)
+ */
+ struct MHD_Connection *eready_tail;
+
+ /**
+ * Pointer to marker used to indicate ITC slot in epoll sets.
+ */
+ const char *epoll_itc_marker;
+#ifdef UPGRADE_SUPPORT
+ /**
+ * Head of EDLL of upgraded connections ready for processing (in epoll mode).
+ */
+ struct MHD_UpgradeResponseHandle *eready_urh_head;
+
+ /**
+ * Tail of EDLL of upgraded connections ready for processing (in epoll mode)
+ */
+ struct MHD_UpgradeResponseHandle *eready_urh_tail;
+#endif /* UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+
+#ifdef DAUTH_SUPPORT
+
+ /**
+ * Character array of random values.
+ */
+ const char *digest_auth_random;
+
+ /**
+ * An array that contains the map nonce-nc.
+ */
+ struct MHD_NonceNc *nnc;
+
+ /**
+ * A rw-lock for synchronizing access to @e nnc.
+ */
+ MHD_mutex_ nnc_lock;
+
+ /**
+ * Size of `digest_auth_random.
+ */
+ size_t digest_auth_rand_size;
+
+ /**
+ * Size of the nonce-nc array.
+ */
+ unsigned int nonce_nc_size;
+
+#endif
+
+ /**
+ * The select thread handle (if we have internal select)
+ */
+ MHD_thread_handle_ID_ pid;
+
+ /**
+ * Socket address to bind to for the listen socket.
+ */
+ struct sockaddr_storage listen_sa;
+
+ /**
+ * Mutex for per-IP connection counts.
+ */
+ MHD_mutex_ per_ip_connection_mutex;
+
+ /**
+ * Mutex for (modifying) access to the "cleanup", "normal_timeout" and
+ * "manual_timeout" DLLs.
+ */
+ MHD_mutex_ cleanup_connection_mutex;
+
+ /**
+ * Number of (valid) bytes in @e listen_sa. Zero
+ * if @e listen_sa is not initialized.
+ */
+ size_t listen_sa_len;
+
+/**
+ * Default size of the per-connection memory pool.
+ */
+#define POOL_SIZE_DEFAULT (32 * 1024)
+ /**
+ * Buffer size to use for each connection. Default
+ * is #POOL_SIZE_DEFAULT.
+ */
+ size_t connection_memory_limit_b;
+
+/**
+ * Default minimum size by which MHD tries to increment read/write
+ * buffers. We usually begin with half the available pool space for
+ * the IO-buffer, but if absolutely needed we additively grow by the
+ * number of bytes given here (up to -- theoretically -- the full pool
+ * space).
+ */
+#define BUF_INC_SIZE_DEFAULT 1024
+
+ /**
+ * Increment to use when growing the read buffer. Smaller
+ * than @e connection_memory_limit_b.
+ */
+ size_t connection_memory_increment_b;
+
+ /**
+ * Desired size of the stack for threads created by MHD,
+ * 0 for system default.
+ */
+ size_t thread_stack_limit_b;
+
+#if ENABLE_DAUTH
+
+ /**
+ * Size of @e digest_auth_random_buf.
+ */
+ size_t digest_auth_random_buf_size;
+
+ /**
+ * Default value for @e digest_nc_length.
+ */
+#define DIGEST_NC_LENGTH_DEFAULT 4
+
+ /**
+ * Desired length of the internal array with the nonce and
+ * nonce counters for digest authentication.
+ */
+ size_t digest_nc_length;
+#endif
+
+ /**
+ * Default value we use for the listen backlog.
+ */
+#ifdef SOMAXCONN
+#define LISTEN_BACKLOG_DEFAULT SOMAXCONN
+#else /* !SOMAXCONN */
+#define LISTEN_BACKLOG_DEFAULT 511
+#endif
+
+ /**
+ * Backlog argument to use for listen. See
+ * #MHD_daemon_listen_backlog().
+ */
+ int listen_backlog;
+
+ /**
+ * Default queue length to use with fast open.
+ */
+#define FO_QUEUE_LENGTH_DEFAULT 50
+
+ /**
+ * Queue length to use with fast open.
+ */
+ unsigned int fo_queue_length;
+
+ /**
+ * Maximum number of connections MHD accepts. 0 for unlimited.
+ */
+ unsigned int global_connection_limit;
+
+ /**
+ * Maximum number of connections we accept per IP, 0 for unlimited.
+ */
+ unsigned int ip_connection_limit;
+
+ /**
+ * Number of active parallel connections.
+ */
+ unsigned int connections;
+
+ /**
+ * Number of worker daemons
+ */
+ unsigned int worker_pool_size;
+
+ /**
+ * Default timeout in seconds for idle connections.
+ */
+ time_t connection_default_timeout;
+
+ /**
+ * Listen socket we should use, MHD_INVALID_SOCKET means
+ * we are to initialize the socket from the other options given.
+ */
+ MHD_socket listen_socket;
+
+#ifdef EPOLL_SUPPORT
+ /**
+ * File descriptor associated with our epoll loop.
+ */
+ int epoll_fd;
+
+ /**
+ * true if the listen socket is in the 'epoll' set,
+ * false if not.
+ */
+ bool listen_socket_in_epoll;
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ /**
+ * File descriptor associated with the #run_epoll_for_upgrade() loop.
+ * Only available if #MHD_USE_HTTPS_EPOLL_UPGRADE is set.
+ */
+ int epoll_upgrade_fd;
+
+ /**
+ * true if @e epoll_upgrade_fd is in the 'epoll' set,
+ * false if not.
+ */
+ bool upgrade_fd_in_epoll;
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+#endif
+
+ /**
+ * Inter-thread communication channel.
+ */
+ struct MHD_itc_ itc;
+
+ /**
+ * Which threading mode do we use? Positive
+ * numbers indicate the number of worker threads to be used.
+ * Values larger than 1 imply a thread pool.
+ */
+ enum MHD_ThreadingMode threading_mode;
+
+ /**
+ * When should we use TCP_FASTOPEN?
+ * See #MHD_daemon_tcp_fastopen().
+ */
+ enum MHD_FastOpenMethod fast_open_method;
+
+ /**
+ * Address family to use when listening.
+ * Default is #MHD_AF_NONE (do not listen).
+ */
+ enum MHD_AddressFamily listen_af;
+
+ /**
+ * Sets active/desired style of the event loop.
+ * (Auto only possible during initialization, later set to
+ * the actual style we use.)
+ */
+ enum MHD_EventLoopSyscall event_loop_syscall;
+
+ /**
+ * How strictly do we enforce the HTTP protocol?
+ * See #MHD_daemon_protocol_strict_level().
+ */
+ enum MHD_ProtocolStrictLevel protocol_strict_level;
+
+ /**
+ * On which port should we listen on? Only effective if we were not
+ * given a listen socket or a full address via
+ * #MHD_daemon_bind_sa(). 0 means to bind to random free port.
+ */
+ uint16_t listen_port;
+
+ /**
+ * Suppress generating the "Date:" header, this system
+ * lacks an RTC (or developer is hyper-optimizing). See
+ * #MHD_daemon_suppress_date_no_clock().
+ */
+ bool suppress_date;
+
+ /**
+ * The use of the inter-thread communication channel is disabled.
+ * See #MHD_daemon_disable_itc().
+ */
+ bool disable_itc;
+
+ /**
+ * Disable #MHD_action_suspend() functionality. See
+ * #MHD_daemon_disallow_suspend_resume().
+ */
+ bool disallow_suspend_resume;
+
+ /**
+ * Disable #MHD_action_upgrade() functionality. See
+ * #MHD_daemon_disallow_upgrade().
+ */
+ bool disallow_upgrade;
+
+ /**
+ * Did we hit some system or process-wide resource limit while
+ * trying to accept() the last time? If so, we don't accept new
+ * connections until we close an existing one. This effectively
+ * temporarily lowers the "connection_limit" to the current
+ * number of connections.
+ */
+ bool at_limit;
+
+ /**
+ * Disables optional calls to `shutdown()` and enables aggressive
+ * non-blocking optimistic reads and other potentially unsafe
+ * optimizations. See #MHD_daemon_enable_turbo().
+ */
+ bool enable_turbo;
+
+ /**
+ * 'True' if some data is already waiting to be processed. If set
+ * to 'true' - zero timeout for select()/poll*() is used. Should be
+ * reset each time before processing connections and raised by any
+ * connection which require additional immediately processing
+ * (application does not provide data for response, data waiting in
+ * TLS buffers etc.)
+ */
+ bool data_already_pending;
+
+ /**
+ * MHD_daemon_quiesce() was run against this daemon.
+ */
+ bool was_quiesced;
+
+ /**
+ * Is some connection wanting to resume?
+ */
+ bool resuming;
+
+ /**
+ * Allow reusing the address:port combination when binding.
+ * See #MHD_daemon_listen_allow_address_reuse().
+ */
+ bool allow_address_reuse;
+
+ /**
+ * MHD should speak SHOUTcast instead of HTTP.
+ */
+ bool enable_shoutcast;
+
+ /**
+ * Are we shutting down?
+ */
+ volatile bool shutdown;
+
+};
+
+
+/**
+ * Action function implementing some action to be
+ * performed on a request.
+ *
+ * @param cls action-specfic closure
+ * @param request the request on which the action is to be performed
+ * @return #MHD_SC_OK on success, otherwise an error code
+ */
+typedef enum MHD_StatusCode
+(*ActionCallback)(void *cls,
+ struct MHD_Request *request);
+
+
+/**
+ * Actions are returned by the application to drive the request
+ * handling of MHD.
+ */
+struct MHD_Action
+{
+
+ /**
+ * Function to call for the action.
+ */
+ ActionCallback action;
+
+ /**
+ * Closure for @a action
+ */
+ void *action_cls;
+
+};
+
+
+/**
+ * Representation of an HTTP response.
+ */
+struct MHD_Response
+{
+
+ /**
+ * A response *is* an action. See also
+ * #MHD_action_from_response(). Hence this field
+ * must be the first field in a response!
+ */
+ struct MHD_Action action;
+
+ /**
+ * Headers to send for the response. Initially
+ * the linked list is created in inverse order;
+ * the order should be inverted before sending!
+ */
+ struct MHD_HTTP_Header *first_header;
+
+ /**
+ * Buffer pointing to data that we are supposed
+ * to send as a response.
+ */
+ char *data;
+
+ /**
+ * Closure to give to the content reader @e crc
+ * and content reader free callback @e crfc.
+ */
+ void *crc_cls;
+
+ /**
+ * How do we get more data? NULL if we are
+ * given all of the data up front.
+ */
+ MHD_ContentReaderCallback crc;
+
+ /**
+ * NULL if data must not be freed, otherwise
+ * either user-specified callback or "&free".
+ */
+ MHD_ContentReaderFreeCallback crfc;
+
+ /**
+ * Function to call once MHD is finished with
+ * the request, may be NULL.
+ */
+ MHD_RequestTerminationCallback termination_cb;
+
+ /**
+ * Closure for @e termination_cb.
+ */
+ void *termination_cb_cls;
+
+#ifdef UPGRADE_SUPPORT
+ /**
+ * Application function to call once we are done sending the headers
+ * of the response; NULL unless this is a response created with
+ * #MHD_create_response_for_upgrade().
+ */
+ MHD_UpgradeHandler upgrade_handler;
+
+ /**
+ * Closure for @e uh.
+ */
+ void *upgrade_handler_cls;
+#endif /* UPGRADE_SUPPORT */
+
+ /**
+ * Mutex to synchronize access to @e data, @e size and
+ * @e reference_count.
+ */
+ MHD_mutex_ mutex;
+
+ /**
+ * Set to #MHD_SIZE_UNKNOWN if size is not known.
+ */
+ uint64_t total_size;
+
+ /**
+ * At what offset in the stream is the
+ * beginning of @e data located?
+ */
+ uint64_t data_start;
+
+ /**
+ * Offset to start reading from when using @e fd.
+ */
+ uint64_t fd_off;
+
+ /**
+ * Number of bytes ready in @e data (buffer may be larger
+ * than what is filled with payload).
+ */
+ size_t data_size;
+
+ /**
+ * Size of the data buffer @e data.
+ */
+ size_t data_buffer_size;
+
+ /**
+ * HTTP status code of the response.
+ */
+ enum MHD_HTTP_StatusCode status_code;
+
+ /**
+ * Reference count for this response. Free once the counter hits
+ * zero.
+ */
+ unsigned int reference_count;
+
+ /**
+ * File-descriptor if this response is FD-backed.
+ */
+ int fd;
+
+ /**
+ * Only respond in HTTP 1.0 mode.
+ */
+ bool v10_only;
+
+ /**
+ * Use ShoutCAST format.
+ */
+ bool icy;
+
+};
+
+
+/**
+ * Callback invoked when iterating over @a key / @a value
+ * argument pairs during parsing.
+ *
+ * @param request context of the iteration
+ * @param key 0-terminated key string, never NULL
+ * @param value 0-terminated value string, may be NULL
+ * @param kind origin of the key-value pair
+ * @return true on success (continue to iterate)
+ * false to signal failure (and abort iteration)
+ */
+typedef bool
+(*MHD_ArgumentIterator_)(struct MHD_Request *request,
+ const char *key,
+ const char *value,
+ enum MHD_ValueKind kind);
+
+
+/**
+ * Parse and unescape the arguments given by the client
+ * as part of the HTTP request URI.
+ *
+ * @param request request to add headers to
+ * @param kind header kind to pass to @a cb
+ * @param[in,out] args argument URI string (after "?" in URI),
+ * clobbered in the process!
+ * @param cb function to call on each key-value pair found
+ * @param[out] num_headers set to the number of headers found
+ * @return false on failure (@a cb returned false),
+ * true for success (parsing succeeded, @a cb always
+ * returned true)
+ */
+bool
+MHD_parse_arguments_ (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ char *args,
+ MHD_ArgumentIterator_ cb,
+ unsigned int *num_headers);
+
+
+/**
+ * Insert an element at the head of a DLL. Assumes that head, tail and
+ * element are structs with prev and next fields.
+ *
+ * @param head pointer to the head of the DLL
+ * @param tail pointer to the tail of the DLL
+ * @param element element to insert
+ */
+#define DLL_insert(head,tail,element) do { \
+ mhd_assert (NULL == (element)->next); \
+ mhd_assert (NULL == (element)->prev); \
+ (element)->next = (head); \
+ (element)->prev = NULL; \
+ if ((tail) == NULL) \
+ (tail) = element; \
+ else \
+ (head)->prev = element; \
+ (head) = (element); } while (0)
+
+
+/**
+ * Remove an element from a DLL. Assumes that head, tail and element
+ * are structs with prev and next fields.
+ *
+ * @param head pointer to the head of the DLL
+ * @param tail pointer to the tail of the DLL
+ * @param element element to remove
+ */
+#define DLL_remove(head,tail,element) do { \
+ mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \
+ mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \
+ if ((element)->prev == NULL) \
+ (head) = (element)->next; \
+ else \
+ (element)->prev->next = (element)->next; \
+ if ((element)->next == NULL) \
+ (tail) = (element)->prev; \
+ else \
+ (element)->next->prev = (element)->prev; \
+ (element)->next = NULL; \
+ (element)->prev = NULL; } while (0)
+
+
+/**
+ * Insert an element at the head of a XDLL. Assumes that head, tail and
+ * element are structs with prevX and nextX fields.
+ *
+ * @param head pointer to the head of the XDLL
+ * @param tail pointer to the tail of the XDLL
+ * @param element element to insert
+ */
+#define XDLL_insert(head,tail,element) do { \
+ mhd_assert (NULL == (element)->nextX); \
+ mhd_assert (NULL == (element)->prevX); \
+ (element)->nextX = (head); \
+ (element)->prevX = NULL; \
+ if (NULL == (tail)) \
+ (tail) = element; \
+ else \
+ (head)->prevX = element; \
+ (head) = (element); } while (0)
+
+
+/**
+ * Remove an element from a XDLL. Assumes that head, tail and element
+ * are structs with prevX and nextX fields.
+ *
+ * @param head pointer to the head of the XDLL
+ * @param tail pointer to the tail of the XDLL
+ * @param element element to remove
+ */
+#define XDLL_remove(head,tail,element) do { \
+ mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \
+ mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \
+ if (NULL == (element)->prevX) \
+ (head) = (element)->nextX; \
+ else \
+ (element)->prevX->nextX = (element)->nextX; \
+ if (NULL == (element)->nextX) \
+ (tail) = (element)->prevX; \
+ else \
+ (element)->nextX->prevX = (element)->prevX; \
+ (element)->nextX = NULL; \
+ (element)->prevX = NULL; } while (0)
+
+
+/**
+ * Insert an element at the head of a EDLL. Assumes that head, tail and
+ * element are structs with prevE and nextE fields.
+ *
+ * @param head pointer to the head of the EDLL
+ * @param tail pointer to the tail of the EDLL
+ * @param element element to insert
+ */
+#define EDLL_insert(head,tail,element) do { \
+ (element)->nextE = (head); \
+ (element)->prevE = NULL; \
+ if ((tail) == NULL) \
+ (tail) = element; \
+ else \
+ (head)->prevE = element; \
+ (head) = (element); } while (0)
+
+
+/**
+ * Remove an element from a EDLL. Assumes that head, tail and element
+ * are structs with prevE and nextE fields.
+ *
+ * @param head pointer to the head of the EDLL
+ * @param tail pointer to the tail of the EDLL
+ * @param element element to remove
+ */
+#define EDLL_remove(head,tail,element) do { \
+ if ((element)->prevE == NULL) \
+ (head) = (element)->nextE; \
+ else \
+ (element)->prevE->nextE = (element)->nextE; \
+ if ((element)->nextE == NULL) \
+ (tail) = (element)->prevE; \
+ else \
+ (element)->nextE->prevE = (element)->prevE; \
+ (element)->nextE = NULL; \
+ (element)->prevE = NULL; } while (0)
+
+
+/**
+ * Error code similar to EGAIN or EINTR
+ */
+#define MHD_ERR_AGAIN_ (-3073)
+
+/**
+ * Connection was hard-closed by remote peer.
+ */
+#define MHD_ERR_CONNRESET_ (-3074)
+
+/**
+ * Connection is not connected anymore due to
+ * network error or any other reason.
+ */
+#define MHD_ERR_NOTCONN_ (-3075)
+
+/**
+ * "Not enough memory" error code
+ */
+#define MHD_ERR_NOMEM_ (-3076)
+
+/**
+ * "Bad FD" error code
+ */
+#define MHD_ERR_BADF_ (-3077)
+
+/**
+ * Error code similar to EINVAL
+ */
+#define MHD_ERR_INVAL_ (-3078)
+
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/md5.c
^
|
@@ -0,0 +1,268 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MHD_MD5Init, call MHD_MD5Update as
+ * needed on buffers full of bytes, and then call MHD_MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* Based on OpenBSD modifications */
+
+#include "md5.h"
+#include "mhd_byteorder.h"
+
+#define PUT_64BIT_LE(cp, value) do { \
+ (cp)[7] = (uint8_t) ((value) >> 56); \
+ (cp)[6] = (uint8_t) ((value) >> 48); \
+ (cp)[5] = (uint8_t) ((value) >> 40); \
+ (cp)[4] = (uint8_t) ((value) >> 32); \
+ (cp)[3] = (uint8_t) ((value) >> 24); \
+ (cp)[2] = (uint8_t) ((value) >> 16); \
+ (cp)[1] = (uint8_t) ((value) >> 8); \
+ (cp)[0] = (uint8_t) ((value)); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do { \
+ (cp)[3] = (uint8_t) ((value) >> 24); \
+ (cp)[2] = (uint8_t) ((value) >> 16); \
+ (cp)[1] = (uint8_t) ((value) >> 8); \
+ (cp)[0] = (uint8_t) ((value)); } while (0)
+
+static uint8_t PADDING[MD5_BLOCK_SIZE] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MHD_MD5Init (struct MD5Context *ctx)
+{
+ if (! ctx)
+ return;
+
+ ctx->count = 0;
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xefcdab89;
+ ctx->state[2] = 0x98badcfe;
+ ctx->state[3] = 0x10325476;
+}
+
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t len)
+{
+ size_t have, need;
+
+ if (! ctx || ! input)
+ return;
+
+ /* Check how many bytes we already have and how many more we need. */
+ have = (size_t) ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
+ need = MD5_BLOCK_SIZE - have;
+
+ /* Update bitcount */
+ ctx->count += (uint64_t) len << 3;
+
+ if (len >= need)
+ {
+ if (have != 0)
+ {
+ memcpy (ctx->buffer + have, input, need);
+ MD5Transform (ctx->state, ctx->buffer);
+ input += need;
+ len -= need;
+ have = 0;
+ }
+
+ /* Process data in MD5_BLOCK_SIZE-byte chunks. */
+ while (len >= MD5_BLOCK_SIZE)
+ {
+ MD5Transform (ctx->state, input);
+ input += MD5_BLOCK_SIZE;
+ len -= MD5_BLOCK_SIZE;
+ }
+ }
+
+ /* Handle any remaining bytes of data. */
+ if (len != 0)
+ memcpy (ctx->buffer + have, input, len);
+}
+
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Pad (struct MD5Context *ctx)
+{
+ uint8_t count[8];
+ size_t padlen;
+
+ if (! ctx)
+ return;
+
+ /* Convert count to 8 bytes in little endian order. */
+ PUT_64BIT_LE (count, ctx->count);
+
+ /* Pad out to 56 mod 64. */
+ padlen = MD5_BLOCK_SIZE
+ - ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
+ if (padlen < 1 + 8)
+ padlen += MD5_BLOCK_SIZE;
+ MHD_MD5Update (ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
+ MHD_MD5Update (ctx, count, 8);
+}
+
+
+/*
+ * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ */
+void
+MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
+{
+ int i;
+
+ if (! ctx || ! digest)
+ return;
+
+ MD5Pad (ctx);
+ for (i = 0; i < 4; i++)
+ PUT_32BIT_LE (digest + i * 4, ctx->state[i]);
+
+ memset (ctx, 0, sizeof(*ctx));
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1 (z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ (w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x)
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
+{
+ uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4];
+
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+ memcpy (in, block, sizeof(in));
+#else
+ for (a = 0; a < MD5_BLOCK_SIZE / 4; a++)
+ {
+ in[a] = (uint32_t) (
+ (uint32_t) (block[a * 4 + 0])
+ | (uint32_t) (block[a * 4 + 1]) << 8
+ | (uint32_t) (block[a * 4 + 2]) << 16
+ | (uint32_t) (block[a * 4 + 3]) << 24);
+ }
+#endif
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+
+ MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
+
+
+/* end of md5.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/md5.h
^
|
@@ -0,0 +1,66 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MHD_MD5Init, call MHD_MD5Update as
+ * needed on buffers full of bytes, and then call MHD_MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#ifndef MHD_MD5_H
+#define MHD_MD5_H
+
+#include "platform.h"
+
+#define MD5_BLOCK_SIZE 64
+#define MD5_DIGEST_SIZE 16
+#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1)
+
+struct MD5Context
+{
+ uint32_t state[4]; /* state */
+ uint64_t count; /* number of bits, mod 2^64 */
+ uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */
+};
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MHD_MD5Init (struct MD5Context *ctx);
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t
+ len);
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Pad (struct MD5Context *ctx);
+
+/*
+ * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ */
+void MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct
+ MD5Context *ctx);
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]);
+
+#endif /* !MHD_MD5_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/memorypool.c
^
|
@@ -0,0 +1,340 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009, 2010, 2018 Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file memorypool.c
+ * @brief memory pool
+ * @author Christian Grothoff
+ */
+#include "memorypool.h"
+
+/* define MAP_ANONYMOUS for Mac OS X */
+#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void*) -1)
+#endif
+
+/**
+ * Align to 2x word size (as GNU libc does).
+ */
+#define ALIGN_SIZE (2 * sizeof(void*))
+
+/**
+ * Round up 'n' to a multiple of ALIGN_SIZE.
+ */
+#define ROUND_TO_ALIGN(n) ((n + (ALIGN_SIZE - 1)) & (~(ALIGN_SIZE - 1)))
+
+
+/**
+ * Handle for a memory pool. Pools are not reentrant and must not be
+ * used by multiple threads.
+ */
+struct MemoryPool
+{
+
+ /**
+ * Pointer to the pool's memory
+ */
+ char *memory;
+
+ /**
+ * Size of the pool.
+ */
+ size_t size;
+
+ /**
+ * Offset of the first unallocated byte.
+ */
+ size_t pos;
+
+ /**
+ * Offset of the last unallocated byte.
+ */
+ size_t end;
+
+ /**
+ * false if pool was malloc'ed, true if mmapped (VirtualAlloc'ed for W32).
+ */
+ bool is_mmap;
+};
+
+
+/**
+ * Free the memory given by @a ptr. Calls "free(ptr)". This function
+ * should be used to free the username returned by
+ * #MHD_digest_auth_get_username().
+ * @note Since v0.9.56
+ *
+ * @param ptr pointer to free.
+ */
+_MHD_EXTERN void
+MHD_free (void *ptr)
+{
+ free (ptr);
+}
+
+
+/**
+ * Create a memory pool.
+ *
+ * @param max maximum size of the pool
+ * @return NULL on error
+ */
+struct MemoryPool *
+MHD_pool_create (size_t max)
+{
+ struct MemoryPool *pool;
+
+ pool = malloc (sizeof (struct MemoryPool));
+ if (NULL == pool)
+ return NULL;
+#if defined(MAP_ANONYMOUS) || defined(_WIN32)
+ if (max <= 32 * 1024)
+ pool->memory = MAP_FAILED;
+ else
+#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
+ pool->memory = mmap (NULL,
+ max,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ 0);
+#elif defined(_WIN32)
+ pool->memory = VirtualAlloc (NULL,
+ max,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE);
+#endif
+#else
+ pool->memory = MAP_FAILED;
+#endif
+ if ( (MAP_FAILED == pool->memory) ||
+ (NULL == pool->memory))
+ {
+ pool->memory = malloc (max);
+ if (NULL == pool->memory)
+ {
+ free (pool);
+ return NULL;
+ }
+ pool->is_mmap = false;
+ }
+ else
+ {
+ pool->is_mmap = true;
+ }
+ pool->pos = 0;
+ pool->end = max;
+ pool->size = max;
+ return pool;
+}
+
+
+/**
+ * Destroy a memory pool.
+ *
+ * @param pool memory pool to destroy
+ */
+void
+MHD_pool_destroy (struct MemoryPool *pool)
+{
+ if (NULL == pool)
+ return;
+ if (! pool->is_mmap)
+ free (pool->memory);
+ else
+#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
+ munmap (pool->memory,
+ pool->size);
+#elif defined(_WIN32)
+ VirtualFree (pool->memory,
+ 0,
+ MEM_RELEASE);
+#else
+ abort ();
+#endif
+ free (pool);
+}
+
+
+/**
+ * Check how much memory is left in the @a pool
+ *
+ * @param pool pool to check
+ * @return number of bytes still available in @a pool
+ */
+size_t
+MHD_pool_get_free (struct MemoryPool *pool)
+{
+ return (pool->end - pool->pos);
+}
+
+
+/**
+ * Allocate size bytes from the pool.
+ *
+ * @param pool memory pool to use for the operation
+ * @param size number of bytes to allocate
+ * @param from_end allocate from end of pool (set to #MHD_YES);
+ * use this for small, persistent allocations that
+ * will never be reallocated
+ * @return NULL if the pool cannot support size more
+ * bytes
+ */
+void *
+MHD_pool_allocate (struct MemoryPool *pool,
+ size_t size,
+ int from_end)
+{
+ void *ret;
+ size_t asize;
+
+ asize = ROUND_TO_ALIGN (size);
+ if ( (0 == asize) && (0 != size) )
+ return NULL; /* size too close to SIZE_MAX */
+ if ( (pool->pos + asize > pool->end) ||
+ (pool->pos + asize < pool->pos))
+ return NULL;
+ if (from_end == MHD_YES)
+ {
+ ret = &pool->memory[pool->end - asize];
+ pool->end -= asize;
+ }
+ else
+ {
+ ret = &pool->memory[pool->pos];
+ pool->pos += asize;
+ }
+ return ret;
+}
+
+
+/**
+ * Reallocate a block of memory obtained from the pool.
+ * This is particularly efficient when growing or
+ * shrinking the block that was last (re)allocated.
+ * If the given block is not the most recently
+ * (re)allocated block, the memory of the previous
+ * allocation may be leaked until the pool is
+ * destroyed (and copying the data maybe required).
+ *
+ * @param pool memory pool to use for the operation
+ * @param old the existing block
+ * @param old_size the size of the existing block
+ * @param new_size the new size of the block
+ * @return new address of the block, or
+ * NULL if the pool cannot support @a new_size
+ * bytes (old continues to be valid for @a old_size)
+ */
+void *
+MHD_pool_reallocate (struct MemoryPool *pool,
+ void *old,
+ size_t old_size,
+ size_t new_size)
+{
+ void *ret;
+ size_t asize;
+
+ asize = ROUND_TO_ALIGN (new_size);
+ if ( (0 == asize) &&
+ (0 != new_size) )
+ return NULL; /* new_size too close to SIZE_MAX */
+ if ( (pool->end < old_size) ||
+ (pool->end < asize) )
+ return NULL; /* unsatisfiable or bogus request */
+
+ if ( (pool->pos >= old_size) &&
+ (&pool->memory[pool->pos - old_size] == old) )
+ {
+ /* was the previous allocation - optimize! */
+ if (pool->pos + asize - old_size <= pool->end)
+ {
+ /* fits */
+ pool->pos += asize - old_size;
+ if (asize < old_size) /* shrinking - zero again! */
+ memset (&pool->memory[pool->pos],
+ 0,
+ old_size - asize);
+ return old;
+ }
+ /* does not fit */
+ return NULL;
+ }
+ if (asize <= old_size)
+ return old; /* cannot shrink, no need to move */
+ if ((pool->pos + asize >= pool->pos) &&
+ (pool->pos + asize <= pool->end))
+ {
+ /* fits */
+ ret = &pool->memory[pool->pos];
+ if (0 != old_size)
+ memmove (ret,
+ old,
+ old_size);
+ pool->pos += asize;
+ return ret;
+ }
+ /* does not fit */
+ return NULL;
+}
+
+
+/**
+ * Clear all entries from the memory pool except
+ * for @a keep of the given @a size. The pointer
+ * returned should be a buffer of @a new_size where
+ * the first @a copy_bytes are from @a keep.
+ *
+ * @param pool memory pool to use for the operation
+ * @param keep pointer to the entry to keep (maybe NULL)
+ * @param copy_bytes how many bytes need to be kept at this address
+ * @param new_size how many bytes should the allocation we return have?
+ * (should be larger or equal to @a copy_bytes)
+ * @return addr new address of @a keep (if it had to change)
+ */
+void *
+MHD_pool_reset (struct MemoryPool *pool,
+ void *keep,
+ size_t copy_bytes,
+ size_t new_size)
+{
+ if ( (NULL != keep) &&
+ (keep != pool->memory) )
+ {
+ if (0 != copy_bytes)
+ memmove (pool->memory,
+ keep,
+ copy_bytes);
+ keep = pool->memory;
+ }
+ pool->end = pool->size;
+ /* technically not needed, but safer to zero out */
+ if (pool->size > copy_bytes)
+ memset (&pool->memory[copy_bytes],
+ 0,
+ pool->size - copy_bytes);
+ if (NULL != keep)
+ pool->pos = ROUND_TO_ALIGN (new_size);
+ return keep;
+}
+
+
+/* end of memorypool.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/memorypool.h
^
|
@@ -0,0 +1,130 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file memorypool.h
+ * @brief memory pool; mostly used for efficient (de)allocation
+ * for each connection and bounding memory use for each
+ * request
+ * @author Christian Grothoff
+ */
+
+#ifndef MEMORYPOOL_H
+#define MEMORYPOOL_H
+
+#include "internal.h"
+
+/**
+ * Opaque handle for a memory pool.
+ * Pools are not reentrant and must not be used
+ * by multiple threads.
+ */
+struct MemoryPool;
+
+
+/**
+ * Create a memory pool.
+ *
+ * @param max maximum size of the pool
+ * @return NULL on error
+ */
+struct MemoryPool *
+MHD_pool_create (size_t max);
+
+
+/**
+ * Destroy a memory pool.
+ *
+ * @param pool memory pool to destroy
+ */
+void
+MHD_pool_destroy (struct MemoryPool *pool);
+
+
+/**
+ * Allocate size bytes from the pool.
+ *
+ * @param pool memory pool to use for the operation
+ * @param size number of bytes to allocate
+ * @param from_end allocate from end of pool (set to #MHD_YES);
+ * use this for small, persistent allocations that
+ * will never be reallocated
+ * @return NULL if the pool cannot support size more
+ * bytes
+ */
+void *
+MHD_pool_allocate (struct MemoryPool *pool,
+ size_t size,
+ int from_end);
+
+
+/**
+ * Reallocate a block of memory obtained from the pool.
+ * This is particularly efficient when growing or
+ * shrinking the block that was last (re)allocated.
+ * If the given block is not the most recently
+ * (re)allocated block, the memory of the previous
+ * allocation may be leaked until the pool is
+ * destroyed (and copying the data maybe required).
+ *
+ * @param pool memory pool to use for the operation
+ * @param old the existing block
+ * @param old_size the size of the existing block
+ * @param new_size the new size of the block
+ * @return new address of the block, or
+ * NULL if the pool cannot support new_size
+ * bytes (old continues to be valid for old_size)
+ */
+void *
+MHD_pool_reallocate (struct MemoryPool *pool,
+ void *old,
+ size_t old_size,
+ size_t new_size);
+
+
+/**
+ * Check how much memory is left in the @a pool
+ *
+ * @param pool pool to check
+ * @return number of bytes still available in @a pool
+ */
+size_t
+MHD_pool_get_free (struct MemoryPool *pool);
+
+
+/**
+ * Clear all entries from the memory pool except
+ * for @a keep of the given @a copy_bytes. The pointer
+ * returned should be a buffer of @a new_size where
+ * the first @a copy_bytes are from @a keep.
+ *
+ * @param pool memory pool to use for the operation
+ * @param keep pointer to the entry to keep (maybe NULL)
+ * @param copy_bytes how many bytes need to be kept at this address
+ * @param new_size how many bytes should the allocation we return have?
+ * (should be larger or equal to @a copy_bytes)
+ * @return addr new address of @a keep (if it had to change)
+ */
+void *
+MHD_pool_reset (struct MemoryPool *pool,
+ void *keep,
+ size_t copy_bytes,
+ size_t new_size);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_assert.h
^
|
@@ -0,0 +1,49 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2017 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_assert.h
+ * @brief macros for mhd_assert()
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_ASSERT_H
+#define MHD_ASSERT_H 1
+
+#include "mhd_options.h"
+#ifdef NDEBUG
+# define mhd_assert(ignore) ((void) 0)
+#else /* _DEBUG */
+# ifdef HAVE_ASSERT
+# include <assert.h>
+# define mhd_assert(CHK) assert (CHK)
+# else /* ! HAVE_ASSERT */
+# include <stdio.h>
+# include <stdlib.h>
+# define mhd_assert(CHK) \
+ do { \
+ if (! (CHK)) { \
+ fprintf (stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \
+ __FILE__, (unsigned) __LINE__, #CHK); \
+ fflush (stderr); abort (); } \
+ } while (0)
+# endif /* ! HAVE_ASSERT */
+#endif /* _DEBUG */
+
+#endif /* ! MHD_ASSERT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_byteorder.h
^
|
@@ -0,0 +1,167 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_byteorder.h
+ * @brief macro definitions for host byte order
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_BYTEORDER_H
+#define MHD_BYTEORDER_H
+
+#include "platform.h"
+
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#if HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+
+#if HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if HAVE_SYS_BYTEORDER_H
+#include <sys/byteorder.h>
+#endif
+
+#if HAVE_SYS_MACHINE_H
+#include <sys/machine.h>
+#endif
+
+#if HAVE_MACHINE_PARAM_H
+#include <machine/param.h>
+#endif
+
+#if HAVE_SYS_ISA_DEFS_H
+#include <sys/isa_defs.h>
+#endif
+
+#define _MHD_BIG_ENDIAN 1234
+#define _MHD_LITTLE_ENDIAN 4321
+#define _MHD_PDP_ENDIAN 2143
+
+#if defined(__BYTE_ORDER__)
+#if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == \
+ __ORDER_LITTLE_ENDIAN__
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
+#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
+#endif /* __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ */
+#elif defined(__BYTE_ORDER)
+#if defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(__PDP_ENDIAN) && __BYTE_ORDER == __PDP_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
+#endif /* __BYTE_ORDER == __PDP_ENDIAN */
+#elif defined (BYTE_ORDER)
+#if defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(LITTLE_ENDIAN) && BYTE_ORDER == LITTLE_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(PDP_ENDIAN) && BYTE_ORDER == PDP_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
+#endif /* __BYTE_ORDER == _PDP_ENDIAN */
+#elif defined (_BYTE_ORDER)
+#if defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(_PDP_ENDIAN) && _BYTE_ORDER == _PDP_ENDIAN
+#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
+#endif /* _BYTE_ORDER == _PDP_ENDIAN */
+#endif /* _BYTE_ORDER */
+
+#ifndef _MHD_BYTE_ORDER
+/* Byte order specification didn't detected in system headers */
+/* Try some guessing */
+
+#if (defined(__BIG_ENDIAN__) && ! defined(__LITTLE_ENDIAN__)) || \
+ (defined(_BIG_ENDIAN) && ! defined(_LITTLE_ENDIAN))
+/* Seems that we are on big endian platform */
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif (defined(__LITTLE_ENDIAN__) && ! defined(__BIG_ENDIAN__)) || \
+ (defined(_LITTLE_ENDIAN) && ! defined(_BIG_ENDIAN))
+/* Seems that we are on little endian platform */
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
+ defined(__x86_64) || \
+ defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \
+ defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+ defined(__i686__) || \
+ defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__)
+/* x86 family is little endian */
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
+ defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
+/* Looks like we are on ARM/MIPS in big endian mode */
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
+ defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
+/* Looks like we are on ARM/MIPS in little endian mode */
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || \
+ defined(__hppa) || \
+ defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \
+ defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
+/* Looks like we are on big endian platform */
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \
+ defined(__ia64) || \
+ defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \
+ defined(__BFIN__) || defined(bfin) || defined(BFIN)
+/* Looks like we are on little endian platform */
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(_WIN32)
+/* W32 is always little endian on all platforms */
+#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
+#elif defined(WORDS_BIGENDIAN)
+/* Use byte order detected by configure */
+#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
+#endif /* _WIN32 */
+
+#endif /* !_MHD_BYTE_ORDER */
+
+#ifdef _MHD_BYTE_ORDER
+/* Some safety checks */
+#if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN
+#error \
+ Configure detected big endian byte order but headers specify different byte order
+#elif ! defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#error \
+ Configure did not detect big endian byte order but headers specify big endian byte order
+#endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
+#endif /* _MHD_BYTE_ORDER */
+
+#endif /* !MHD_BYTEORDER_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_compat.c
^
|
@@ -0,0 +1,118 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_compat.c
+ * @brief Implementation of platform missing functions.
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_compat.h"
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+#include <stdint.h>
+#include <time.h>
+#ifndef HAVE_SNPRINTF
+#include <stdio.h>
+#include <stdarg.h>
+#endif /* HAVE_SNPRINTF */
+#endif /* _WIN32 && !__CYGWIN__ */
+
+#ifndef HAVE_CALLOC
+#include <string.h> /* for memset() */
+#endif /* ! HAVE_CALLOC */
+
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+
+#ifndef HAVE_SNPRINTF
+/* Emulate snprintf function on W32 */
+int
+W32_snprintf (char *__restrict s,
+ size_t n,
+ const char *__restrict format,
+ ...)
+{
+ int ret;
+ va_list args;
+
+ if ( (0 != n) &&
+ (NULL != s) )
+ {
+ va_start (args,
+ format);
+ ret = _vsnprintf (s,
+ n,
+ format,
+ args);
+ va_end (args);
+ if ((int) n == ret)
+ s[n - 1] = 0;
+ if (ret >= 0)
+ return ret;
+ }
+ va_start (args,
+ format);
+ ret = _vscprintf (format,
+ args);
+ va_end (args);
+ if ( (0 <= ret) &&
+ (0 != n) &&
+ (NULL == s) )
+ return -1;
+
+ return ret;
+}
+
+
+#endif /* HAVE_SNPRINTF */
+#endif /* _WIN32 && !__CYGWIN__ */
+
+#ifndef HAVE_CALLOC
+
+#ifdef __has_builtin
+# if __has_builtin (__builtin_mul_overflow)
+# define MHD_HAVE_NUL_OVERFLOW 1
+# endif
+#elif __GNUC__ + 0 >= 5
+# define MHD_HAVE_NUL_OVERFLOW 1
+#endif /* __GNUC__ >= 5 */
+
+
+void *
+MHD_calloc_ (size_t nelem, size_t elsize)
+{
+ size_t alloc_size;
+ void *ptr;
+#ifdef MHD_HAVE_NUL_OVERFLOW
+ if (__builtin_mul_overflow (nelem, elsize, &alloc_size) || (0 == alloc_size))
+ return NULL;
+#else /* ! MHD_HAVE_NUL_OVERFLOW */
+ alloc_size = nelem * elsize;
+ if ((0 == alloc_size) || (elsize != alloc_size / nelem))
+ return NULL;
+#endif /* ! MHD_HAVE_NUL_OVERFLOW */
+ ptr = malloc (alloc_size);
+ if (NULL == ptr)
+ return NULL;
+ memset (ptr, 0, alloc_size);
+ return ptr;
+}
+
+
+#endif /* ! HAVE_CALLOC */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_compat.h
^
|
@@ -0,0 +1,91 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_compat.h
+ * @brief Header for platform missing functions.
+ * @author Karlson2k (Evgeny Grin)
+ *
+ * Provides compatibility for platforms with some missing
+ * functionality.
+ * Any functions can be implemented as macro on some platforms
+ * unless explicitly marked otherwise.
+ * Any function argument can be skipped in macro, so avoid
+ * variable modification in function parameters.
+ */
+
+#ifndef MHD_COMPAT_H
+#define MHD_COMPAT_H 1
+
+#include "mhd_options.h"
+#include <stdlib.h>
+#ifdef HAVE_STRING_H /* for strerror() */
+#include <string.h>
+#endif /* HAVE_STRING_H */
+
+/* MHD_strerror_ is strerror */
+#define MHD_strerror_(errnum) strerror ((errnum))
+
+/* Platform-independent snprintf name */
+#if defined(HAVE_SNPRINTF)
+#define MHD_snprintf_ snprintf
+#else /* ! HAVE_SNPRINTF */
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+/* Emulate snprintf function on W32 */
+int W32_snprintf (char *__restrict s, size_t n, const char *__restrict format,
+ ...);
+
+#define MHD_snprintf_ W32_snprintf
+#else /* ! _WIN32 || __CYGWIN__ */
+#error \
+ Your platform does not support snprintf() and MHD does not know how to emulate it on your platform.
+#endif /* ! _WIN32 || __CYGWIN__ */
+#endif /* ! HAVE_SNPRINTF */
+
+#ifdef HAVE_RANDOM
+/**
+ * Generate pseudo random number at least 30-bit wide.
+ * @return pseudo random number at least 30-bit wide.
+ */
+#define MHD_random_() random ()
+#else /* HAVE_RANDOM */
+#ifdef HAVE_RAND
+/**
+ * Generate pseudo random number at least 30-bit wide.
+ * @return pseudo random number at least 30-bit wide.
+ */
+#define MHD_random_() ( (((long) rand ()) << 15) + (long) rand () )
+#endif /* HAVE_RAND */
+#endif /* HAVE_RANDOM */
+
+#ifdef HAVE_CALLOC
+/**
+ * MHD_calloc_ is platform-independent calloc()
+ */
+#define MHD_calloc_(n,s) calloc ((n),(s))
+#else /* ! HAVE_CALLOC */
+/**
+ * MHD_calloc_ is platform-independent calloc()
+ */
+void *MHD_calloc_ (size_t nelem, size_t elsize);
+
+#endif /* ! HAVE_CALLOC */
+
+#endif /* MHD_COMPAT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_itc.c
^
|
@@ -0,0 +1,72 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_itc.c
+ * @brief Implementation of inter-thread communication functions
+ * @author Karlson2k (Evgeny Grin)
+ * @author Christian Grothoff
+ */
+
+#include "mhd_itc.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
+#include "internal.h"
+
+
+#if defined(_MHD_ITC_PIPE)
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+
+#ifndef HAVE_PIPE2_FUNC
+/**
+ * Change itc FD options to be non-blocking.
+ *
+ * @param itc the inter-thread communication primitive to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_itc_nonblocking_ (struct MHD_itc_ itc)
+{
+ unsigned int i;
+
+ for (i = 0; i<2; i++)
+ {
+ int flags;
+
+ flags = fcntl (itc.fd[i],
+ F_GETFL);
+ if (-1 == flags)
+ return 0;
+
+ if ( ((flags | O_NONBLOCK) != flags) &&
+ (0 != fcntl (itc.fd[i],
+ F_SETFL,
+ flags | O_NONBLOCK)) )
+ return 0;
+ }
+ return ! 0;
+}
+
+
+#endif /* ! HAVE_PIPE2_FUNC */
+#endif /* !_WIN32 || __CYGWIN__ */
+#endif /* _MHD_ITC_EVENTFD || _MHD_ITC_PIPE */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_itc.h
^
|
@@ -0,0 +1,369 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_itc.h
+ * @brief Header for platform-independent inter-thread communication
+ * @author Karlson2k (Evgeny Grin)
+ * @author Christian Grothoff
+ *
+ * Provides basic abstraction for inter-thread communication.
+ * Any functions can be implemented as macro on some platforms
+ * unless explicitly marked otherwise.
+ * Any function argument can be skipped in macro, so avoid
+ * variable modification in function parameters.
+ */
+#ifndef MHD_ITC_H
+#define MHD_ITC_H 1
+#include "mhd_itc_types.h"
+
+#include <fcntl.h>
+
+#ifndef MHD_PANIC
+# include <stdio.h>
+# include <stdlib.h>
+/* Simple implementation of MHD_PANIC, to be used outside lib */
+# define MHD_PANIC(msg) do { fprintf (stderr, \
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
+#endif /* ! MHD_PANIC */
+
+#if defined(_MHD_ITC_EVENTFD)
+
+/* **************** Optimized GNU/Linux ITC implementation by eventfd ********** */
+#include <sys/eventfd.h>
+#include <stdint.h> /* for uint64_t */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for read(), write(), errno */
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_STRING_H
+#include <string.h> /* for strerror() */
+#endif
+
+
+/**
+ * Initialise ITC by generating eventFD
+ * @param itc the itc to initialise
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
+ | EFD_NONBLOCK)))
+
+/**
+ * Get description string of last errno for itc operations.
+ */
+#define MHD_itc_last_strerror_() strerror (errno)
+
+/**
+ * Internal static const helper for MHD_itc_activate_()
+ */
+static const uint64_t _MHD_itc_wr_data = 1;
+
+/**
+ * Activate signal on @a itc
+ * @param itc the itc to use
+ * @param str ignored
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_activate_(itc, str) \
+ ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
+ errno))
+
+/**
+ * Return read FD of @a itc which can be used for poll(), select() etc.
+ * @param itc the itc to get FD
+ * @return FD of read side
+ */
+#define MHD_itc_r_fd_(itc) ((itc).fd)
+
+/**
+ * Return write FD of @a itc
+ * @param itc the itc to get FD
+ * @return FD of write side
+ */
+#define MHD_itc_w_fd_(itc) ((itc).fd)
+
+/**
+ * Clear signaled state on @a itc
+ * @param itc the itc to clear
+ */
+#define MHD_itc_clear_(itc) \
+ do { uint64_t __b; int __r; \
+ __r = read ((itc).fd, &__b, sizeof(__b)); \
+ (void) __r; } while (0)
+
+/**
+ * Destroy previously initialised ITC. Note that close()
+ * on some platforms returns odd errors, so we ONLY fail
+ * if the errno is EBADF.
+ * @param itc the itc to destroy
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_destroy_(itc) ((0 == close ((itc).fd)) || (EBADF != errno))
+
+/**
+ * Check whether ITC has valid value.
+ *
+ * Macro check whether @a itc value is valid (allowed),
+ * macro does not check whether @a itc was really initialised.
+ * @param itc the itc to check
+ * @return boolean true if @a itc has valid value,
+ * boolean false otherwise.
+ */
+#define MHD_ITC_IS_VALID_(itc) (-1 != ((itc).fd))
+
+/**
+ * Set @a itc to invalid value.
+ * @param itc the itc to set
+ */
+#define MHD_itc_set_invalid_(itc) ((itc).fd = -1)
+
+
+#elif defined(_MHD_ITC_PIPE)
+
+/* **************** Standard UNIX ITC implementation by pipe ********** */
+
+#if defined(HAVE_PIPE2_FUNC) && defined(HAVE_FCNTL_H)
+# include <fcntl.h> /* for O_CLOEXEC, O_NONBLOCK */
+#endif /* HAVE_PIPE2_FUNC && HAVE_FCNTL_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for read(), write(), errno */
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_STRING_H
+#include <string.h> /* for strerror() */
+#endif
+
+
+/**
+ * Initialise ITC by generating pipe
+ * @param itc the itc to initialise
+ * @return non-zero if succeeded, zero otherwise
+ */
+#ifdef HAVE_PIPE2_FUNC
+# define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
+#else /* ! HAVE_PIPE2_FUNC */
+# define MHD_itc_init_(itc) \
+ ( (! pipe ((itc).fd)) ? \
+ (MHD_itc_nonblocking_ ((itc)) ? \
+ (! 0) : \
+ (MHD_itc_destroy_ ((itc)), 0) ) \
+ : (0) )
+#endif /* ! HAVE_PIPE2_FUNC */
+
+/**
+ * Get description string of last errno for itc operations.
+ */
+#define MHD_itc_last_strerror_() strerror (errno)
+
+/**
+ * Activate signal on @a itc
+ * @param itc the itc to use
+ * @param str one-symbol string, useful only for strace debug
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_activate_(itc, str) \
+ ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
+
+
+/**
+ * Return read FD of @a itc which can be used for poll(), select() etc.
+ * @param itc the itc to get FD
+ * @return FD of read side
+ */
+#define MHD_itc_r_fd_(itc) ((itc).fd[0])
+
+/**
+ * Return write FD of @a itc
+ * @param itc the itc to get FD
+ * @return FD of write side
+ */
+#define MHD_itc_w_fd_(itc) ((itc).fd[1])
+
+/**
+ * Clear signaled state on @a itc
+ * @param itc the itc to clear
+ */
+#define MHD_itc_clear_(itc) do \
+ { long __b; \
+ while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
+ {} } while (0)
+
+/**
+ * Destroy previously initialised ITC
+ * @param itc the itc to destroy
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_destroy_(itc) \
+ ( (0 == close ((itc).fd[0])) ? \
+ (0 == close ((itc).fd[1])) : \
+ ((close ((itc).fd[1])), 0) )
+
+/**
+ * Check whether ITC has valid value.
+ *
+ * Macro check whether @a itc value is valid (allowed),
+ * macro does not check whether @a itc was really initialised.
+ * @param itc the itc to check
+ * @return boolean true if @a itc has valid value,
+ * boolean false otherwise.
+ */
+#define MHD_ITC_IS_VALID_(itc) (-1 != (itc).fd[0])
+
+/**
+ * Set @a itc to invalid value.
+ * @param itc the itc to set
+ */
+#define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
+
+#ifndef HAVE_PIPE2_FUNC
+/**
+ * Change itc FD options to be non-blocking.
+ *
+ * @param fd the FD to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_itc_nonblocking_ (struct MHD_itc_ itc);
+
+#endif /* ! HAVE_PIPE2_FUNC */
+
+
+#elif defined(_MHD_ITC_SOCKETPAIR)
+
+/* **************** ITC implementation by socket pair ********** */
+
+#include "mhd_sockets.h"
+
+
+/**
+ * Initialise ITC by generating socketpair
+ * @param itc the itc to initialise
+ * @return non-zero if succeeded, zero otherwise
+ */
+#ifdef MHD_socket_pair_nblk_
+# define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
+#else /* ! MHD_socket_pair_nblk_ */
+# define MHD_itc_init_(itc) \
+ (MHD_socket_pair_ ((itc).sk) ? \
+ (MHD_itc_nonblocking_ ((itc)) ? \
+ (! 0) : \
+ (MHD_itc_destroy_ ((itc)), 0) ) \
+ : (0))
+#endif /* ! MHD_socket_pair_nblk_ */
+
+/**
+ * Get description string of last error for itc operations.
+ */
+#define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
+
+/**
+ * Activate signal on @a itc
+ * @param itc the itc to use
+ * @param str one-symbol string, useful only for strace debug
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_activate_(itc, str) \
+ ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
+ (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
+
+/**
+ * Return read FD of @a itc which can be used for poll(), select() etc.
+ * @param itc the itc to get FD
+ * @return FD of read side
+ */
+#define MHD_itc_r_fd_(itc) ((itc).sk[0])
+
+/**
+ * Return write FD of @a itc
+ * @param itc the itc to get FD
+ * @return FD of write side
+ */
+#define MHD_itc_w_fd_(itc) ((itc).sk[1])
+
+/**
+ * Clear signaled state on @a itc
+ * @param itc the itc to clear
+ */
+#define MHD_itc_clear_(itc) do \
+ { long __b; \
+ while (0 < recv ((itc).sk[0], \
+ (char*) &__b, \
+ sizeof(__b), 0)) \
+ {} } while (0)
+
+/**
+ * Destroy previously initialised ITC
+ * @param itc the itc to destroy
+ * @return non-zero if succeeded, zero otherwise
+ */
+#define MHD_itc_destroy_(itc) \
+ (MHD_socket_close_ ((itc).sk[0]) ? \
+ MHD_socket_close_ ((itc).sk[1]) : \
+ ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
+
+
+/**
+ * Check whether ITC has valid value.
+ *
+ * Macro check whether @a itc value is valid (allowed),
+ * macro does not check whether @a itc was really initialised.
+ * @param itc the itc to check
+ * @return boolean true if @a itc has valid value,
+ * boolean false otherwise.
+ */
+#define MHD_ITC_IS_VALID_(itc) (MHD_INVALID_SOCKET != (itc).sk[0])
+
+/**
+ * Set @a itc to invalid value.
+ * @param itc the itc to set
+ */
+#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
+ MHD_INVALID_SOCKET)
+
+#ifndef MHD_socket_pair_nblk_
+# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
+ MHD_socket_nonblocking_ ((pip).sk[1]))
+#endif /* ! MHD_socket_pair_nblk_ */
+
+#endif /* _MHD_ITC_SOCKETPAIR */
+
+/**
+ * Destroy previously initialised ITC and abort execution
+ * if error is detected.
+ * @param itc the itc to destroy
+ */
+#define MHD_itc_destroy_chk_(itc) do { \
+ if (! MHD_itc_destroy_ (itc)) \
+ MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
+} while (0)
+
+/**
+ * Check whether ITC has invalid value.
+ *
+ * Macro check whether @a itc value is invalid,
+ * macro does not check whether @a itc was destroyed.
+ * @param itc the itc to check
+ * @return boolean true if @a itc has invalid value,
+ * boolean false otherwise.
+ */
+#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
+
+#endif /* MHD_ITC_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_itc_types.h
^
|
@@ -0,0 +1,77 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin), Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_itc_types.h
+ * @brief Types for platform-independent inter-thread communication
+ * @author Karlson2k (Evgeny Grin)
+ * @author Christian Grothoff
+ *
+ * Provides basic types for inter-thread communication.
+ * Designed to be included by other headers.
+ */
+#ifndef MHD_ITC_TYPES_H
+#define MHD_ITC_TYPES_H 1
+#include "mhd_options.h"
+
+/* Force socketpair on native W32 */
+#if defined(_WIN32) && ! defined(__CYGWIN__) && ! defined(_MHD_ITC_SOCKETPAIR)
+#error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform
+#endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */
+
+#if defined(_MHD_ITC_EVENTFD)
+/* **************** Optimized GNU/Linux ITC implementation by eventfd ********** */
+
+/**
+ * Data type for a MHD ITC.
+ */
+struct MHD_itc_
+{
+ int fd;
+};
+
+#elif defined(_MHD_ITC_PIPE)
+/* **************** Standard UNIX ITC implementation by pipe ********** */
+
+/**
+ * Data type for a MHD ITC.
+ */
+struct MHD_itc_
+{
+ int fd[2];
+};
+
+
+#elif defined(_MHD_ITC_SOCKETPAIR)
+/* **************** ITC implementation by socket pair ********** */
+
+#include "mhd_sockets.h"
+
+/**
+ * Data type for a MHD ITC.
+ */
+struct MHD_itc_
+{
+ MHD_socket sk[2];
+};
+
+#endif /* _MHD_ITC_SOCKETPAIR */
+
+#endif /* ! MHD_ITC_TYPES_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_limits.h
^
|
@@ -0,0 +1,154 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/mhd_limits.h
+ * @brief limits values definitions
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_LIMITS_H
+#define MHD_LIMITS_H
+
+#include "platform.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif /* HAVE_LIMITS_H */
+
+#define MHD_UNSIGNED_TYPE_MAX_(type) ((type) - 1)
+/* Assume 8 bits per byte, no padding bits. */
+#define MHD_SIGNED_TYPE_MAX_(type) \
+ ( (type) ((( ((type) 1) << (sizeof(type) * 8 - 2)) - 1) * 2 + 1) )
+#define MHD_TYPE_IS_SIGNED_(type) (((type) 0)>((type) - 1))
+
+#ifndef UINT_MAX
+#ifdef __UINT_MAX__
+#define UINT_MAX __UINT_MAX__
+#else /* ! __UINT_MAX__ */
+#define UINT_MAX MHD_UNSIGNED_TYPE_MAX_ (unsigned int)
+#endif /* ! __UINT_MAX__ */
+#endif /* !UINT_MAX */
+
+#ifndef LONG_MAX
+#ifdef __LONG_MAX__
+#define LONG_MAX __LONG_MAX__
+#else /* ! __LONG_MAX__ */
+#define LONG_MAX MHD_SIGNED_TYPE_MAX (long)
+#endif /* ! __LONG_MAX__ */
+#endif /* !OFF_T_MAX */
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_ (MHD_UNSIGNED_LONG_LONG)
+#endif /* !ULLONG_MAX */
+
+#ifndef INT32_MAX
+#ifdef __INT32_MAX__
+#define INT32_MAX __INT32_MAX__
+#else /* ! __INT32_MAX__ */
+#define INT32_MAX ((int32_t) 0x7FFFFFFF)
+#endif /* ! __INT32_MAX__ */
+#endif /* !INT32_MAX */
+
+#ifndef UINT32_MAX
+#ifdef __UINT32_MAX__
+#define UINT32_MAX __UINT32_MAX__
+#else /* ! __UINT32_MAX__ */
+#define UINT32_MAX ((int32_t) 0xFFFFFFFF)
+#endif /* ! __UINT32_MAX__ */
+#endif /* !UINT32_MAX */
+
+#ifndef UINT64_MAX
+#ifdef __UINT64_MAX__
+#define UINT64_MAX __UINT64_MAX__
+#else /* ! __UINT64_MAX__ */
+#define UINT64_MAX ((uint64_t) 0xFFFFFFFFFFFFFFFF)
+#endif /* ! __UINT64_MAX__ */
+#endif /* !UINT64_MAX */
+
+#ifndef INT64_MAX
+#ifdef __INT64_MAX__
+#define INT64_MAX __INT64_MAX__
+#else /* ! __INT64_MAX__ */
+#define INT64_MAX ((int64_t) 0x7FFFFFFFFFFFFFFF)
+#endif /* ! __UINT64_MAX__ */
+#endif /* !INT64_MAX */
+
+#ifndef SIZE_MAX
+#ifdef __SIZE_MAX__
+#define SIZE_MAX __SIZE_MAX__
+#elif defined(UINTPTR_MAX)
+#define SIZE_MAX UINTPTR_MAX
+#else /* ! __SIZE_MAX__ */
+#define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_ (size_t)
+#endif /* ! __SIZE_MAX__ */
+#endif /* !SIZE_MAX */
+
+#ifndef SSIZE_MAX
+#ifdef __SSIZE_MAX__
+#define SSIZE_MAX __SSIZE_MAX__
+#elif defined(PTRDIFF_MAX)
+#define SSIZE_MAX PTRDIFF_MAX
+#elif defined(INTPTR_MAX)
+#define SSIZE_MAX INTPTR_MAX
+#else
+#define SSIZE_MAN MHD_SIGNED_TYPE_MAX_ (ssize_t)
+#endif
+#endif /* ! SSIZE_MAX */
+
+#ifndef OFF_T_MAX
+#ifdef OFF_MAX
+#define OFF_T_MAX OFF_MAX
+#elif defined(OFFT_MAX)
+#define OFF_T_MAX OFFT_MAX
+#elif defined(__APPLE__) && defined(__MACH__)
+#define OFF_T_MAX INT64_MAX
+#else
+#define OFF_T_MAX MHD_SIGNED_TYPE_MAX_ (off_t)
+#endif
+#endif /* !OFF_T_MAX */
+
+#if defined(_LARGEFILE64_SOURCE) && ! defined(OFF64_T_MAX)
+#define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_ (uint64_t)
+#endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */
+
+#ifndef TIME_T_MAX
+#define TIME_T_MAX ((time_t) \
+ (MHD_TYPE_IS_SIGNED_ (time_t) ? \
+ MHD_SIGNED_TYPE_MAX_ (time_t) : \
+ MHD_UNSIGNED_TYPE_MAX_ (time_t)))
+#endif /* !TIME_T_MAX */
+
+#ifndef TIMEVAL_TV_SEC_MAX
+#ifndef _WIN32
+#define TIMEVAL_TV_SEC_MAX TIME_T_MAX
+#else /* _WIN32 */
+#define TIMEVAL_TV_SEC_MAX LONG_MAX
+#endif /* _WIN32 */
+#endif /* !TIMEVAL_TV_SEC_MAX */
+
+#ifndef MHD_FD_BLOCK_SIZE
+#ifdef _WIN32
+#define MHD_FD_BLOCK_SIZE 16384 /* 16k */
+#else /* _WIN32 */
+#define MHD_FD_BLOCK_SIZE 4096 /* 4k */
+#endif /* _WIN32 */
+#endif /* !MHD_FD_BLOCK_SIZE */
+
+#endif /* MHD_LIMITS_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_locks.h
^
|
@@ -0,0 +1,186 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_locks.h
+ * @brief Header for platform-independent locks abstraction
+ * @author Karlson2k (Evgeny Grin)
+ * @author Christian Grothoff
+ *
+ * Provides basic abstraction for locks/mutex.
+ * Any functions can be implemented as macro on some platforms
+ * unless explicitly marked otherwise.
+ * Any function argument can be skipped in macro, so avoid
+ * variable modification in function parameters.
+ *
+ * @warning Unlike pthread functions, most of functions return
+ * nonzero on success.
+ */
+
+#ifndef MHD_LOCKS_H
+#define MHD_LOCKS_H 1
+
+#include "mhd_options.h"
+
+#if defined(MHD_USE_W32_THREADS)
+# define MHD_W32_MUTEX_ 1
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif /* !WIN32_LEAN_AND_MEAN */
+# include <windows.h>
+#elif defined(HAVE_PTHREAD_H) && defined(MHD_USE_POSIX_THREADS)
+# define MHD_PTHREAD_MUTEX_ 1
+# undef HAVE_CONFIG_H
+# include <pthread.h>
+# define HAVE_CONFIG_H 1
+#else
+# error No base mutex API is available.
+#endif
+
+#ifndef MHD_PANIC
+# include <stdio.h>
+# include <stdlib.h>
+/* Simple implementation of MHD_PANIC, to be used outside lib */
+# define MHD_PANIC(msg) do { fprintf (stderr, \
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
+#endif /* ! MHD_PANIC */
+
+#if defined(MHD_PTHREAD_MUTEX_)
+typedef pthread_mutex_t MHD_mutex_;
+#elif defined(MHD_W32_MUTEX_)
+typedef CRITICAL_SECTION MHD_mutex_;
+#endif
+
+#if defined(MHD_PTHREAD_MUTEX_)
+/**
+ * Initialise new mutex.
+ * @param pmutex pointer to the mutex
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_mutex_init_(pmutex) (! (pthread_mutex_init ((pmutex), NULL)))
+#elif defined(MHD_W32_MUTEX_)
+/**
+ * Initialise new mutex.
+ * @param pmutex pointer to mutex
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount ( \
+ (pmutex),16))
+#endif
+
+#if defined(MHD_PTHREAD_MUTEX_)
+# if defined(PTHREAD_MUTEX_INITIALIZER)
+/**
+ * Define static mutex and statically initialise it.
+ */
+# define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = \
+ PTHREAD_MUTEX_INITIALIZER
+# endif /* PTHREAD_MUTEX_INITIALIZER */
+#endif
+
+#if defined(MHD_PTHREAD_MUTEX_)
+/**
+ * Destroy previously initialised mutex.
+ * @param pmutex pointer to mutex
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_mutex_destroy_(pmutex) (! (pthread_mutex_destroy ((pmutex))))
+#elif defined(MHD_W32_MUTEX_)
+/**
+ * Destroy previously initialised mutex.
+ * @param pmutex pointer to mutex
+ * @return Always nonzero
+ */
+#define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection ((pmutex)), ! 0)
+#endif
+
+/**
+ * Destroy previously initialised mutex and abort execution
+ * if error is detected.
+ * @param pmutex pointer to mutex
+ */
+#define MHD_mutex_destroy_chk_(pmutex) do { \
+ if (! MHD_mutex_destroy_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to destroy mutex.\n")); \
+} while (0)
+
+
+#if defined(MHD_PTHREAD_MUTEX_)
+/**
+ * Acquire lock on previously initialised mutex.
+ * If mutex was already locked by other thread, function
+ * blocks until mutex becomes available.
+ * @param pmutex pointer to mutex
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_mutex_lock_(pmutex) (! (pthread_mutex_lock ((pmutex))))
+#elif defined(MHD_W32_MUTEX_)
+/**
+ * Acquire lock on previously initialised mutex.
+ * If mutex was already locked by other thread, function
+ * blocks until mutex becomes available.
+ * @param pmutex pointer to mutex
+ * @return Always nonzero
+ */
+#define MHD_mutex_lock_(pmutex) (EnterCriticalSection ((pmutex)), ! 0)
+#endif
+
+/**
+ * Acquire lock on previously initialised mutex.
+ * If mutex was already locked by other thread, function
+ * blocks until mutex becomes available.
+ * If error is detected, execution will be aborted.
+ * @param pmutex pointer to mutex
+ */
+#define MHD_mutex_lock_chk_(pmutex) do { \
+ if (! MHD_mutex_lock_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to lock mutex.\n")); \
+} while (0)
+
+#if defined(MHD_PTHREAD_MUTEX_)
+/**
+ * Unlock previously initialised and locked mutex.
+ * @param pmutex pointer to mutex
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_mutex_unlock_(pmutex) (! (pthread_mutex_unlock ((pmutex))))
+#elif defined(MHD_W32_MUTEX_)
+/**
+ * Unlock previously initialised and locked mutex.
+ * @param pmutex pointer to mutex
+ * @return Always nonzero
+ */
+#define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection ((pmutex)), ! 0)
+#endif
+
+/**
+ * Unlock previously initialised and locked mutex.
+ * If error is detected, execution will be aborted.
+ * @param pmutex pointer to mutex
+ */
+#define MHD_mutex_unlock_chk_(pmutex) do { \
+ if (! MHD_mutex_unlock_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to unlock mutex.\n")); \
+} while (0)
+
+
+#endif /* ! MHD_LOCKS_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_mono_clock.c
^
|
@@ -0,0 +1,378 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/mhd_mono_clock.h
+ * @brief internal monotonic clock functions implementations
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_mono_clock.h"
+
+#if defined(_WIN32) && ! defined(__CYGWIN__) && defined(HAVE_CLOCK_GETTIME)
+/* Prefer native clock source over wrappers */
+#undef HAVE_CLOCK_GETTIME
+#endif /* _WIN32 && ! __CYGWIN__ && HAVE_CLOCK_GETTIME */
+
+#ifdef HAVE_CLOCK_GETTIME
+#include <time.h>
+#endif /* HAVE_CLOCK_GETTIME */
+
+#ifdef HAVE_GETHRTIME
+#ifdef HAVE_SYS_TIME_H
+/* Solaris defines gethrtime() in sys/time.h */
+#include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+#ifdef HAVE_TIME_H
+/* HP-UX defines gethrtime() in time.h */
+#include <time.h>
+#endif /* HAVE_TIME_H */
+#endif /* HAVE_GETHRTIME */
+
+#ifdef HAVE_CLOCK_GET_TIME
+#include <mach/mach.h>
+/* for host_get_clock_service(), mach_host_self(), mach_task_self() */
+#include <mach/clock.h>
+/* for clock_get_time() */
+
+#define _MHD_INVALID_CLOCK_SERV ((clock_serv_t) -2)
+
+static clock_serv_t mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+#endif /* HAVE_CLOCK_GET_TIME */
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+/* Do not include unneeded parts of W32 headers. */
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#include <stdint.h>
+#endif /* _WIN32 */
+
+#ifdef HAVE_CLOCK_GETTIME
+#ifdef CLOCK_REALTIME
+#define _MHD_UNWANTED_CLOCK CLOCK_REALTIME
+#else /* !CLOCK_REALTIME */
+#define _MHD_UNWANTED_CLOCK ((clockid_t) -2)
+#endif /* !CLOCK_REALTIME */
+
+static clockid_t mono_clock_id = _MHD_UNWANTED_CLOCK;
+#endif /* HAVE_CLOCK_GETTIME */
+
+/* sync clocks; reduce chance of value wrap */
+#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || \
+ defined(HAVE_GETHRTIME)
+static time_t mono_clock_start;
+#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */
+static time_t sys_clock_start;
+#ifdef HAVE_GETHRTIME
+static hrtime_t hrtime_start;
+#endif /* HAVE_GETHRTIME */
+#ifdef _WIN32
+#if _WIN32_WINNT >= 0x0600
+static uint64_t tick_start;
+#else /* _WIN32_WINNT < 0x0600 */
+static int64_t perf_freq;
+static int64_t perf_start;
+#endif /* _WIN32_WINNT < 0x0600 */
+#endif /* _WIN32 */
+
+
+/**
+ * Type of monotonic clock source
+ */
+enum _MHD_mono_clock_source
+{
+ /**
+ * No monotonic clock
+ */
+ _MHD_CLOCK_NO_SOURCE = 0,
+
+ /**
+ * clock_gettime() with specific clock
+ */
+ _MHD_CLOCK_GETTIME,
+
+ /**
+ * clock_get_time() with specific clock service
+ */
+ _MHD_CLOCK_GET_TIME,
+
+ /**
+ * gethrtime() / 1000000000
+ */
+ _MHD_CLOCK_GETHRTIME,
+
+ /**
+ * GetTickCount64() / 1000
+ */
+ _MHD_CLOCK_GETTICKCOUNT64,
+
+ /**
+ * QueryPerformanceCounter() / QueryPerformanceFrequency()
+ */
+ _MHD_CLOCK_PERFCOUNTER
+};
+
+
+/**
+ * Initialise monotonic seconds counter.
+ */
+void
+MHD_monotonic_sec_counter_init (void)
+{
+#ifdef HAVE_CLOCK_GET_TIME
+ mach_timespec_t cur_time;
+#endif /* HAVE_CLOCK_GET_TIME */
+ enum _MHD_mono_clock_source mono_clock_source = _MHD_CLOCK_NO_SOURCE;
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec ts;
+
+ mono_clock_id = _MHD_UNWANTED_CLOCK;
+#endif /* HAVE_CLOCK_GETTIME */
+#ifdef HAVE_CLOCK_GET_TIME
+ mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+#endif /* HAVE_CLOCK_GET_TIME */
+
+ /* just a little syntactic trick to get the
+ various following ifdef's to work out nicely */
+ if (0)
+ {
+ }
+ else
+#ifdef HAVE_CLOCK_GETTIME
+#ifdef CLOCK_MONOTONIC_COARSE
+ /* Linux-specific fast value-getting clock */
+ /* Can be affected by frequency adjustment and don't count time in suspend, */
+ /* but preferred since it's fast */
+ if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE,
+ &ts))
+ {
+ mono_clock_id = CLOCK_MONOTONIC_COARSE;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_MONOTONIC_COARSE */
+#ifdef CLOCK_MONOTONIC_FAST
+ /* FreeBSD/DragonFly fast value-getting clock */
+ /* Can be affected by frequency adjustment, but preferred since it's fast */
+ if (0 == clock_gettime (CLOCK_MONOTONIC_FAST,
+ &ts))
+ {
+ mono_clock_id = CLOCK_MONOTONIC_FAST;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_MONOTONIC_COARSE */
+#ifdef CLOCK_MONOTONIC_RAW
+ /* Linux-specific clock */
+ /* Not affected by frequency adjustment, but don't count time in suspend */
+ if (0 == clock_gettime (CLOCK_MONOTONIC_RAW,
+ &ts))
+ {
+ mono_clock_id = CLOCK_MONOTONIC_RAW;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_MONOTONIC_RAW */
+#ifdef CLOCK_BOOTTIME
+ /* Linux-specific clock */
+ /* Count time in suspend so it's real monotonic on Linux, */
+ /* but can be slower value-getting than other clocks */
+ if (0 == clock_gettime (CLOCK_BOOTTIME,
+ &ts))
+ {
+ mono_clock_id = CLOCK_BOOTTIME;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_BOOTTIME */
+#ifdef CLOCK_MONOTONIC
+ /* Monotonic clock */
+ /* Widely supported, may be affected by frequency adjustment */
+ /* On Linux it's not truly monotonic as it doesn't count time in suspend */
+ if (0 == clock_gettime (CLOCK_MONOTONIC,
+ &ts))
+ {
+ mono_clock_id = CLOCK_MONOTONIC;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_BOOTTIME */
+#endif /* HAVE_CLOCK_GETTIME */
+#ifdef HAVE_CLOCK_GET_TIME
+ /* Darwin-specific monotonic clock */
+ /* Should be monotonic as clock_set_time function always unconditionally */
+ /* failed on latest kernels */
+ if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self (),
+ SYSTEM_CLOCK,
+ &mono_clock_service)) &&
+ (KERN_SUCCESS == clock_get_time (mono_clock_service,
+ &cur_time)) )
+ {
+ mono_clock_start = cur_time.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GET_TIME;
+ }
+ else
+#endif /* HAVE_CLOCK_GET_TIME */
+#ifdef _WIN32
+#if _WIN32_WINNT >= 0x0600
+ /* W32 Vista or later specific monotonic clock */
+ /* Available since Vista, ~15ms accuracy */
+ if (1)
+ {
+ tick_start = GetTickCount64 ();
+ mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64;
+ }
+ else
+#else /* _WIN32_WINNT < 0x0600 */
+ /* W32 specific monotonic clock */
+ /* Available on Windows 2000 and later */
+ if (1)
+ {
+ LARGE_INTEGER freq;
+ LARGE_INTEGER perf_counter;
+
+ QueryPerformanceFrequency (&freq); /* never fail on XP and later */
+ QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
+ perf_freq = freq.QuadPart;
+ perf_start = perf_counter.QuadPart;
+ mono_clock_source = _MHD_CLOCK_PERFCOUNTER;
+ }
+ else
+#endif /* _WIN32_WINNT < 0x0600 */
+#endif /* _WIN32 */
+#ifdef HAVE_CLOCK_GETTIME
+#ifdef CLOCK_HIGHRES
+ /* Solaris-specific monotonic high-resolution clock */
+ /* Not preferred due to be potentially resource-hungry */
+ if (0 == clock_gettime (CLOCK_HIGHRES,
+ &ts))
+ {
+ mono_clock_id = CLOCK_HIGHRES;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
+ else
+#endif /* CLOCK_HIGHRES */
+#endif /* HAVE_CLOCK_GETTIME */
+#ifdef HAVE_GETHRTIME
+ /* HP-UX and Solaris monotonic clock */
+ /* Not preferred due to be potentially resource-hungry */
+ if (1)
+ {
+ hrtime_start = gethrtime ();
+ mono_clock_source = _MHD_CLOCK_GETHRTIME;
+ }
+ else
+#endif /* HAVE_GETHRTIME */
+ {
+ /* no suitable clock source was found */
+ mono_clock_source = _MHD_CLOCK_NO_SOURCE;
+ }
+
+#ifdef HAVE_CLOCK_GET_TIME
+ if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) &&
+ (_MHD_INVALID_CLOCK_SERV != mono_clock_service) )
+ {
+ /* clock service was initialised but clock_get_time failed */
+ mach_port_deallocate (mach_task_self (),
+ mono_clock_service);
+ mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+ }
+#else
+ (void) mono_clock_source; /* avoid compiler warning */
+#endif /* HAVE_CLOCK_GET_TIME */
+
+ sys_clock_start = time (NULL);
+}
+
+
+/**
+ * Deinitialise monotonic seconds counter by freeing any allocated resources
+ */
+void
+MHD_monotonic_sec_counter_finish (void)
+{
+#ifdef HAVE_CLOCK_GET_TIME
+ if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
+ {
+ mach_port_deallocate (mach_task_self (),
+ mono_clock_service);
+ mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+ }
+#endif /* HAVE_CLOCK_GET_TIME */
+}
+
+
+/**
+ * Monotonic seconds counter, useful for timeout calculation.
+ * Tries to be not affected by manually setting the system real time
+ * clock or adjustments by NTP synchronization.
+ *
+ * @return number of seconds from some fixed moment
+ */
+time_t
+MHD_monotonic_sec_counter (void)
+{
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec ts;
+
+ if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) &&
+ (0 == clock_gettime (mono_clock_id,
+ &ts)) )
+ return ts.tv_sec - mono_clock_start;
+#endif /* HAVE_CLOCK_GETTIME */
+#ifdef HAVE_CLOCK_GET_TIME
+ if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
+ {
+ mach_timespec_t cur_time;
+
+ if (KERN_SUCCESS == clock_get_time (mono_clock_service,
+ &cur_time))
+ return cur_time.tv_sec - mono_clock_start;
+ }
+#endif /* HAVE_CLOCK_GET_TIME */
+#if defined(_WIN32)
+#if _WIN32_WINNT >= 0x0600
+ if (1)
+ return (time_t) (((uint64_t) (GetTickCount64 () - tick_start)) / 1000);
+#else /* _WIN32_WINNT < 0x0600 */
+ if (0 != perf_freq)
+ {
+ LARGE_INTEGER perf_counter;
+
+ QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
+ return (time_t) (((uint64_t) (perf_counter.QuadPart - perf_start))
+ / perf_freq);
+ }
+#endif /* _WIN32_WINNT < 0x0600 */
+#endif /* _WIN32 */
+#ifdef HAVE_GETHRTIME
+ if (1)
+ return (time_t) (((uint64_t) (gethrtime () - hrtime_start)) / 1000000000);
+#endif /* HAVE_GETHRTIME */
+
+ return time (NULL) - sys_clock_start;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_mono_clock.h
^
|
@@ -0,0 +1,60 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/mhd_mono_clock.h
+ * @brief internal monotonic clock functions declarations
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_MONO_CLOCK_H
+#define MHD_MONO_CLOCK_H 1
+#include "mhd_options.h"
+
+#if defined(HAVE_TIME_H)
+#include <time.h>
+#elif defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+/**
+ * Initialise monotonic seconds counter.
+ */
+void
+MHD_monotonic_sec_counter_init (void);
+
+
+/**
+ * Deinitialise monotonic seconds counter by freeing any allocated resources
+ */
+void
+MHD_monotonic_sec_counter_finish (void);
+
+
+/**
+ * Monotonic seconds counter, useful for timeout calculation.
+ * Tries to be not affected by manually setting the system real time
+ * clock or adjustments by NTP synchronization.
+ *
+ * @return number of seconds from some fixed moment
+ */
+time_t
+MHD_monotonic_sec_counter (void);
+
+#endif /* MHD_MONO_CLOCK_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_sockets.c
^
|
@@ -0,0 +1,517 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_sockets.c
+ * @brief Implementation for sockets functions
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_sockets.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
+
+#ifdef MHD_WINSOCK_SOCKETS
+
+/**
+ * Return pointer to string description of specified WinSock error
+ * @param err the WinSock error code.
+ * @return pointer to string description of specified WinSock error.
+ */
+const char*
+MHD_W32_strerror_winsock_ (int err)
+{
+ switch (err)
+ {
+ case 0:
+ return "No error";
+ case WSA_INVALID_HANDLE:
+ return "Specified event object handle is invalid";
+ case WSA_NOT_ENOUGH_MEMORY:
+ return "Insufficient memory available";
+ case WSA_INVALID_PARAMETER:
+ return "One or more parameters are invalid";
+ case WSA_OPERATION_ABORTED:
+ return "Overlapped operation aborted";
+ case WSA_IO_INCOMPLETE:
+ return "Overlapped I/O event object not in signaled state";
+ case WSA_IO_PENDING:
+ return "Overlapped operations will complete later";
+ case WSAEINTR:
+ return "Interrupted function call";
+ case WSAEBADF:
+ return "File handle is not valid";
+ case WSAEACCES:
+ return "Permission denied";
+ case WSAEFAULT:
+ return "Bad address";
+ case WSAEINVAL:
+ return "Invalid argument";
+ case WSAEMFILE:
+ return "Too many open files";
+ case WSAEWOULDBLOCK:
+ return "Resource temporarily unavailable";
+ case WSAEINPROGRESS:
+ return "Operation now in progress";
+ case WSAEALREADY:
+ return "Operation already in progress";
+ case WSAENOTSOCK:
+ return "Socket operation on nonsocket";
+ case WSAEDESTADDRREQ:
+ return "Destination address required";
+ case WSAEMSGSIZE:
+ return "Message too long";
+ case WSAEPROTOTYPE:
+ return "Protocol wrong type for socket";
+ case WSAENOPROTOOPT:
+ return "Bad protocol option";
+ case WSAEPROTONOSUPPORT:
+ return "Protocol not supported";
+ case WSAESOCKTNOSUPPORT:
+ return "Socket type not supported";
+ case WSAEOPNOTSUPP:
+ return "Operation not supported";
+ case WSAEPFNOSUPPORT:
+ return "Protocol family not supported";
+ case WSAEAFNOSUPPORT:
+ return "Address family not supported by protocol family";
+ case WSAEADDRINUSE:
+ return "Address already in use";
+ case WSAEADDRNOTAVAIL:
+ return "Cannot assign requested address";
+ case WSAENETDOWN:
+ return "Network is down";
+ case WSAENETUNREACH:
+ return "Network is unreachable";
+ case WSAENETRESET:
+ return "Network dropped connection on reset";
+ case WSAECONNABORTED:
+ return "Software caused connection abort";
+ case WSAECONNRESET:
+ return "Connection reset by peer";
+ case WSAENOBUFS:
+ return "No buffer space available";
+ case WSAEISCONN:
+ return "Socket is already connected";
+ case WSAENOTCONN:
+ return "Socket is not connected";
+ case WSAESHUTDOWN:
+ return "Cannot send after socket shutdown";
+ case WSAETOOMANYREFS:
+ return "Too many references";
+ case WSAETIMEDOUT:
+ return "Connection timed out";
+ case WSAECONNREFUSED:
+ return "Connection refused";
+ case WSAELOOP:
+ return "Cannot translate name";
+ case WSAENAMETOOLONG:
+ return "Name too long";
+ case WSAEHOSTDOWN:
+ return "Host is down";
+ case WSAEHOSTUNREACH:
+ return "No route to host";
+ case WSAENOTEMPTY:
+ return "Directory not empty";
+ case WSAEPROCLIM:
+ return "Too many processes";
+ case WSAEUSERS:
+ return "User quota exceeded";
+ case WSAEDQUOT:
+ return "Disk quota exceeded";
+ case WSAESTALE:
+ return "Stale file handle reference";
+ case WSAEREMOTE:
+ return "Item is remote";
+ case WSASYSNOTREADY:
+ return "Network subsystem is unavailable";
+ case WSAVERNOTSUPPORTED:
+ return "Winsock.dll version out of range";
+ case WSANOTINITIALISED:
+ return "Successful WSAStartup not yet performed";
+ case WSAEDISCON:
+ return "Graceful shutdown in progress";
+ case WSAENOMORE:
+ return "No more results";
+ case WSAECANCELLED:
+ return "Call has been canceled";
+ case WSAEINVALIDPROCTABLE:
+ return "Procedure call table is invalid";
+ case WSAEINVALIDPROVIDER:
+ return "Service provider is invalid";
+ case WSAEPROVIDERFAILEDINIT:
+ return "Service provider failed to initialize";
+ case WSASYSCALLFAILURE:
+ return "System call failure";
+ case WSASERVICE_NOT_FOUND:
+ return "Service not found";
+ case WSATYPE_NOT_FOUND:
+ return "Class type not found";
+ case WSA_E_NO_MORE:
+ return "No more results";
+ case WSA_E_CANCELLED:
+ return "Call was canceled";
+ case WSAEREFUSED:
+ return "Database query was refused";
+ case WSAHOST_NOT_FOUND:
+ return "Host not found";
+ case WSATRY_AGAIN:
+ return "Nonauthoritative host not found";
+ case WSANO_RECOVERY:
+ return "This is a nonrecoverable error";
+ case WSANO_DATA:
+ return "Valid name, no data record of requested type";
+ case WSA_QOS_RECEIVERS:
+ return "QoS receivers";
+ case WSA_QOS_SENDERS:
+ return "QoS senders";
+ case WSA_QOS_NO_SENDERS:
+ return "No QoS senders";
+ case WSA_QOS_NO_RECEIVERS:
+ return "QoS no receivers";
+ case WSA_QOS_REQUEST_CONFIRMED:
+ return "QoS request confirmed";
+ case WSA_QOS_ADMISSION_FAILURE:
+ return "QoS admission error";
+ case WSA_QOS_POLICY_FAILURE:
+ return "QoS policy failure";
+ case WSA_QOS_BAD_STYLE:
+ return "QoS bad style";
+ case WSA_QOS_BAD_OBJECT:
+ return "QoS bad object";
+ case WSA_QOS_TRAFFIC_CTRL_ERROR:
+ return "QoS traffic control error";
+ case WSA_QOS_GENERIC_ERROR:
+ return "QoS generic error";
+ case WSA_QOS_ESERVICETYPE:
+ return "QoS service type error";
+ case WSA_QOS_EFLOWSPEC:
+ return "QoS flowspec error";
+ case WSA_QOS_EPROVSPECBUF:
+ return "Invalid QoS provider buffer";
+ case WSA_QOS_EFILTERSTYLE:
+ return "Invalid QoS filter style";
+ case WSA_QOS_EFILTERTYPE:
+ return "Invalid QoS filter type";
+ case WSA_QOS_EFILTERCOUNT:
+ return "Incorrect QoS filter count";
+ case WSA_QOS_EOBJLENGTH:
+ return "Invalid QoS object length";
+ case WSA_QOS_EFLOWCOUNT:
+ return "Incorrect QoS flow count";
+ case WSA_QOS_EUNKOWNPSOBJ:
+ return "Unrecognized QoS object";
+ case WSA_QOS_EPOLICYOBJ:
+ return "Invalid QoS policy object";
+ case WSA_QOS_EFLOWDESC:
+ return "Invalid QoS flow descriptor";
+ case WSA_QOS_EPSFLOWSPEC:
+ return "Invalid QoS provider-specific flowspec";
+ case WSA_QOS_EPSFILTERSPEC:
+ return "Invalid QoS provider-specific filterspec";
+ case WSA_QOS_ESDMODEOBJ:
+ return "Invalid QoS shape discard mode object";
+ case WSA_QOS_ESHAPERATEOBJ:
+ return "Invalid QoS shaping rate object";
+ case WSA_QOS_RESERVED_PETYPE:
+ return "Reserved policy QoS element type";
+ }
+ return "Unknown winsock error";
+}
+
+
+/**
+ * Create pair of mutually connected TCP/IP sockets on loopback address
+ * @param sockets_pair array to receive resulted sockets
+ * @param non_blk if set to non-zero value, sockets created in non-blocking mode
+ * otherwise sockets will be in blocking mode
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk)
+{
+ int i;
+
+ if (! sockets_pair)
+ {
+ WSASetLastError (WSAEFAULT);
+ return 0;
+ }
+
+#define PAIRMAXTRYIES 800
+ for (i = 0; i < PAIRMAXTRYIES; i++)
+ {
+ struct sockaddr_in listen_addr;
+ SOCKET listen_s;
+ static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
+ int addr_len = c_addinlen;
+ unsigned long on_val = 1;
+ unsigned long off_val = 0;
+
+ listen_s = socket (AF_INET,
+ SOCK_STREAM,
+ IPPROTO_TCP);
+ if (INVALID_SOCKET == listen_s)
+ break; /* can't create even single socket */
+
+ listen_addr.sin_family = AF_INET;
+ listen_addr.sin_port = 0; /* same as htons(0) */
+ listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if ( ((0 == bind (listen_s,
+ (struct sockaddr*) &listen_addr,
+ c_addinlen)) &&
+ (0 == listen (listen_s,
+ 1) ) &&
+ (0 == getsockname (listen_s,
+ (struct sockaddr*) &listen_addr,
+ &addr_len))) )
+ {
+ SOCKET client_s = socket (AF_INET,
+ SOCK_STREAM,
+ IPPROTO_TCP);
+ struct sockaddr_in accepted_from_addr;
+ struct sockaddr_in client_addr;
+ SOCKET server_s;
+
+ if (INVALID_SOCKET == client_s)
+ {
+ /* try again */
+ closesocket (listen_s);
+ continue;
+ }
+
+ if ( (0 != ioctlsocket (client_s,
+ FIONBIO,
+ &on_val)) ||
+ ( (0 != connect (client_s,
+ (struct sockaddr*) &listen_addr,
+ c_addinlen)) &&
+ (WSAGetLastError () != WSAEWOULDBLOCK)) )
+ {
+ /* try again */
+ closesocket (listen_s);
+ closesocket (client_s);
+ continue;
+ }
+
+ addr_len = c_addinlen;
+ server_s = accept (listen_s,
+ (struct sockaddr*) &accepted_from_addr,
+ &addr_len);
+ if (INVALID_SOCKET == server_s)
+ {
+ /* try again */
+ closesocket (listen_s);
+ closesocket (client_s);
+ continue;
+ }
+
+ addr_len = c_addinlen;
+ if ( (0 == getsockname (client_s,
+ (struct sockaddr*) &client_addr,
+ &addr_len)) &&
+ (accepted_from_addr.sin_family == client_addr.sin_family) &&
+ (accepted_from_addr.sin_port == client_addr.sin_port) &&
+ (accepted_from_addr.sin_addr.s_addr ==
+ client_addr.sin_addr.s_addr) &&
+ ( (0 != non_blk) ?
+ (0 == ioctlsocket (server_s,
+ FIONBIO,
+ &on_val)) :
+ (0 == ioctlsocket (client_s,
+ FIONBIO,
+ &off_val)) ) )
+ {
+ closesocket (listen_s);
+ sockets_pair[0] = server_s;
+ sockets_pair[1] = client_s;
+ return ! 0;
+ }
+ closesocket (server_s);
+ closesocket (client_s);
+ }
+ closesocket (listen_s);
+ }
+
+ sockets_pair[0] = INVALID_SOCKET;
+ sockets_pair[1] = INVALID_SOCKET;
+ WSASetLastError (WSAECONNREFUSED);
+
+ return 0;
+}
+
+
+#endif /* MHD_WINSOCK_SOCKETS */
+
+
+/**
+ * Add @a fd to the @a set. If @a fd is
+ * greater than @a max_fd, set @a max_fd to @a fd.
+ *
+ * @param fd file descriptor to add to the @a set
+ * @param set set to modify
+ * @param max_fd maximum value to potentially update
+ * @param fd_setsize value of FD_SETSIZE
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_add_to_fd_set_ (MHD_socket fd,
+ fd_set *set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
+{
+ if ( (NULL == set) ||
+ (MHD_INVALID_SOCKET == fd) )
+ return 0;
+ if (! MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (fd,
+ set,
+ fd_setsize))
+ return 0;
+ MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_ (fd,
+ set,
+ fd_setsize);
+ if ( (NULL != max_fd) &&
+ ( (fd > *max_fd) ||
+ (MHD_INVALID_SOCKET == *max_fd) ) )
+ *max_fd = fd;
+ return ! 0;
+}
+
+
+/**
+ * Change socket options to be non-blocking.
+ *
+ * @param sock socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_socket_nonblocking_ (MHD_socket sock)
+{
+#if defined(MHD_POSIX_SOCKETS)
+ int flags;
+
+ flags = fcntl (sock,
+ F_GETFL);
+ if (-1 == flags)
+ return 0;
+
+ if ( ((flags | O_NONBLOCK) != flags) &&
+ (0 != fcntl (sock,
+ F_SETFL,
+ flags | O_NONBLOCK)) )
+ return 0;
+#elif defined(MHD_WINSOCK_SOCKETS)
+ unsigned long flags = 1;
+
+ if (0 != ioctlsocket (sock,
+ FIONBIO,
+ &flags))
+ return 0;
+#endif /* MHD_WINSOCK_SOCKETS */
+ return ! 0;
+}
+
+
+/**
+ * Change socket options to be non-inheritable.
+ *
+ * @param sock socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ * @warning Does not set socket error on W32.
+ */
+int
+MHD_socket_noninheritable_ (MHD_socket sock)
+{
+#if defined(MHD_POSIX_SOCKETS)
+ int flags;
+
+ flags = fcntl (sock,
+ F_GETFD);
+ if (-1 == flags)
+ return 0;
+
+ if ( ((flags | FD_CLOEXEC) != flags) &&
+ (0 != fcntl (sock,
+ F_SETFD,
+ flags | FD_CLOEXEC)) )
+ return 0;
+#elif defined(MHD_WINSOCK_SOCKETS)
+ if (! SetHandleInformation ((HANDLE) sock,
+ HANDLE_FLAG_INHERIT,
+ 0))
+ return 0;
+#endif /* MHD_WINSOCK_SOCKETS */
+ return ! 0;
+}
+
+
+/**
+ * Create a listen socket, with noninheritable flag if possible.
+ *
+ * @param pf protocol family to use
+ * @return created socket or MHD_INVALID_SOCKET in case of errors
+ */
+MHD_socket
+MHD_socket_create_listen_ (int pf)
+{
+ MHD_socket fd;
+ int cloexec_set;
+
+#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC)
+ fd = socket (pf,
+ SOCK_STREAM | SOCK_CLOEXEC,
+ 0);
+ cloexec_set = ! 0;
+#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
+ fd = WSASocketW (pf,
+ SOCK_STREAM,
+ 0,
+ NULL,
+ 0,
+ WSA_FLAG_NO_HANDLE_INHERIT);
+ cloexec_set = ! 0;
+#else /* !SOCK_CLOEXEC */
+ fd = MHD_INVALID_SOCKET;
+#endif /* !SOCK_CLOEXEC */
+ if (MHD_INVALID_SOCKET == fd)
+ {
+ fd = socket (pf,
+ SOCK_STREAM,
+ 0);
+ cloexec_set = 0;
+ }
+ if (MHD_INVALID_SOCKET == fd)
+ return MHD_INVALID_SOCKET;
+#ifdef MHD_socket_nosignal_
+ if (! MHD_socket_nosignal_ (fd))
+ {
+ const int err = MHD_socket_get_error_ ();
+ (void) MHD_socket_close_ (fd);
+ MHD_socket_fset_error_ (err);
+ return MHD_INVALID_SOCKET;
+ }
+#endif /* MHD_socket_nosignal_ */
+ if (! cloexec_set)
+ (void) MHD_socket_noninheritable_ (fd);
+
+ return fd;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_sockets.h
^
|
@@ -0,0 +1,804 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_sockets.c
+ * @brief Header for platform-independent sockets abstraction
+ * @author Karlson2k (Evgeny Grin)
+ *
+ * Provides basic abstraction for sockets.
+ * Any functions can be implemented as macro on some platforms
+ * unless explicitly marked otherwise.
+ * Any function argument can be skipped in macro, so avoid
+ * variable modification in function parameters.
+ */
+
+#ifndef MHD_SOCKETS_H
+#define MHD_SOCKETS_H 1
+#include "mhd_options.h"
+
+#include <errno.h>
+
+#if ! defined(MHD_POSIX_SOCKETS) && ! defined(MHD_WINSOCK_SOCKETS)
+# if ! defined(_WIN32) || defined(__CYGWIN__)
+# define MHD_POSIX_SOCKETS 1
+# else /* defined(_WIN32) && !defined(__CYGWIN__) */
+# define MHD_WINSOCK_SOCKETS 1
+# endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+#endif /* !MHD_POSIX_SOCKETS && !MHD_WINSOCK_SOCKETS */
+
+/*
+ * MHD require headers that define socket type, socket basic functions
+ * (socket(), accept(), listen(), bind(), send(), recv(), select()), socket
+ * parameters like SOCK_CLOEXEC, SOCK_NONBLOCK, additional socket functions
+ * (poll(), epoll(), accept4()), struct timeval and other types, required
+ * for socket function.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h> /* required on old platforms */
+# endif
+# ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+# endif
+# if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS)
+# ifdef HAVE_SOCKLIB_H
+# include <sockLib.h>
+# endif /* HAVE_SOCKLIB_H */
+# ifdef HAVE_INETLIB_H
+# include <inetLib.h>
+# endif /* HAVE_INETLIB_H */
+# include <strings.h> /* required for FD_SET (bzero() function) */
+# endif /* __VXWORKS__ || __vxworks || OS_VXWORKS */
+# ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif /* HAVE_NETINET_IN_H */
+# ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+# ifdef HAVE_NET_IF_H
+# include <net/if.h>
+# endif
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
+# ifdef HAVE_TIME_H
+# include <time.h>
+# endif
+# ifdef HAVE_NETDB_H
+# include <netdb.h>
+# endif
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# endif
+# ifdef EPOLL_SUPPORT
+# include <sys/epoll.h>
+# endif
+# ifdef HAVE_NETINET_TCP_H
+/* for TCP_FASTOPEN and TCP_CORK */
+# include <netinet/tcp.h>
+# endif
+# ifdef HAVE_STRING_H
+# include <string.h> /* for strerror() */
+# endif
+#elif defined(MHD_WINSOCK_SOCKETS)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif /* !WIN32_LEAN_AND_MEAN */
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif /* MHD_WINSOCK_SOCKETS */
+
+#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+# include <poll.h>
+#endif
+
+#include <stddef.h>
+#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
+# include <stdint.h>
+# define _SSIZE_T_DEFINED
+typedef intptr_t ssize_t;
+#endif /* !_SSIZE_T_DEFINED */
+
+#include "mhd_limits.h"
+
+#ifdef _MHD_FD_SETSIZE_IS_DEFAULT
+# define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE
+#else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
+# include "sysfdsetsize.h"
+# define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value ()
+#endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
+
+#ifndef MHD_PANIC
+# include <stdio.h>
+# include <stdlib.h>
+/* Simple implementation of MHD_PANIC, to be used outside lib */
+# define MHD_PANIC(msg) do { fprintf (stderr, \
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
+#endif /* ! MHD_PANIC */
+
+#ifndef MHD_SOCKET_DEFINED
+/**
+ * MHD_socket is type for socket FDs
+ */
+# if defined(MHD_POSIX_SOCKETS)
+typedef int MHD_socket;
+# define MHD_INVALID_SOCKET (-1)
+# elif defined(MHD_WINSOCK_SOCKETS)
+typedef SOCKET MHD_socket;
+# define MHD_INVALID_SOCKET (INVALID_SOCKET)
+# endif /* MHD_WINSOCK_SOCKETS */
+
+# define MHD_SOCKET_DEFINED 1
+#endif /* ! MHD_SOCKET_DEFINED */
+
+#ifdef SOCK_CLOEXEC
+# define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC
+#else /* ! SOCK_CLOEXEC */
+# define MAYBE_SOCK_CLOEXEC 0
+#endif /* ! SOCK_CLOEXEC */
+
+#ifdef HAVE_SOCK_NONBLOCK
+# define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK
+#else /* ! HAVE_SOCK_NONBLOCK */
+# define MAYBE_SOCK_NONBLOCK 0
+#endif /* ! HAVE_SOCK_NONBLOCK */
+
+#ifdef MSG_NOSIGNAL
+# define MAYBE_MSG_NOSIGNAL MSG_NOSIGNAL
+#else /* ! MSG_NOSIGNAL */
+# define MAYBE_MSG_NOSIGNAL 0
+#endif /* ! MSG_NOSIGNAL */
+
+#if ! defined(SHUT_WR) && defined(SD_SEND)
+# define SHUT_WR SD_SEND
+#endif
+#if ! defined(SHUT_RD) && defined(SD_RECEIVE)
+# define SHUT_RD SD_RECEIVE
+#endif
+#if ! defined(SHUT_RDWR) && defined(SD_BOTH)
+# define SHUT_RDWR SD_BOTH
+#endif
+
+#if HAVE_ACCEPT4 + 0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || \
+ defined(SOCK_CLOEXEC))
+# define USE_ACCEPT4 1
+#endif
+
+#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
+# define USE_EPOLL_CREATE1 1
+#endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */
+
+#ifdef TCP_FASTOPEN
+/**
+ * Default TCP fastopen queue size.
+ */
+#define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
+#endif
+
+
+/**
+ * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt()
+ */
+#ifdef MHD_POSIX_SOCKETS
+typedef int MHD_SCKT_OPT_BOOL_;
+#else /* MHD_WINSOCK_SOCKETS */
+typedef BOOL MHD_SCKT_OPT_BOOL_;
+#endif /* MHD_WINSOCK_SOCKETS */
+
+/**
+ * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv
+ * functions
+ */
+#if ! defined(MHD_WINSOCK_SOCKETS)
+typedef size_t MHD_SCKT_SEND_SIZE_;
+#else
+typedef int MHD_SCKT_SEND_SIZE_;
+#endif
+
+/**
+ * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value.
+ */
+#if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX
+#else
+# define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX
+#endif
+
+/**
+ * MHD_socket_close_(fd) close any FDs (non-W32) / close only socket
+ * FDs (W32). Note that on HP-UNIX, this function may leak the FD if
+ * errno is set to EINTR. Do not use HP-UNIX.
+ *
+ * @param fd descriptor to close
+ * @return boolean true on success (error codes like EINTR and EIO are
+ * counted as success, only EBADF counts as an error!),
+ * boolean false otherwise.
+ */
+#if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_close_(fd) ((0 == close ((fd))) || (EBADF != errno))
+#else
+# define MHD_socket_close_(fd) (0 == closesocket ((fd)))
+#endif
+
+/**
+ * MHD_socket_close_chk_(fd) close socket and abort execution
+ * if error is detected.
+ * @param fd socket to close
+ */
+#define MHD_socket_close_chk_(fd) do { \
+ if (! MHD_socket_close_ (fd)) \
+ MHD_PANIC (_ ("Close socket failed.\n")); \
+} while (0)
+
+
+/**
+ * MHD_send_ is wrapper for system's send()
+ * @param s the socket to use
+ * @param b the buffer with data to send
+ * @param l the length of data in @a b
+ * @return ssize_t type value
+ */
+#define MHD_send_(s,b,l) \
+ ((ssize_t) send ((s),(const void*) (b),((MHD_SCKT_SEND_SIZE_) l), \
+ MAYBE_MSG_NOSIGNAL))
+
+
+/**
+ * MHD_recv_ is wrapper for system's recv()
+ * @param s the socket to use
+ * @param b the buffer for data to receive
+ * @param l the length of @a b
+ * @return ssize_t type value
+ */
+#define MHD_recv_(s,b,l) \
+ ((ssize_t) recv ((s),(void*) (b),((MHD_SCKT_SEND_SIZE_) l), 0))
+
+
+/**
+ * Check whether FD can be added to fd_set with specified FD_SETSIZE.
+ * @param fd the fd to check
+ * @param pset the pointer to fd_set to check or NULL to check
+ * whether FD can be used with fd_sets.
+ * @param setsize the value of FD_SETSIZE.
+ * @return boolean true if FD can be added to fd_set,
+ * boolean false otherwise.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < \
+ ((MHD_socket) \
+ setsize))
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*) (pset)== \
+ (void*) 0) || \
+ (((fd_set*) (pset)) \
+ ->fd_count < \
+ ((unsigned) \
+ setsize)) || \
+ (FD_ISSET ((fd), \
+ (pset))) )
+#endif
+
+/**
+ * Check whether FD can be added to fd_set with current FD_SETSIZE.
+ * @param fd the fd to check
+ * @param pset the pointer to fd_set to check or NULL to check
+ * whether FD can be used with fd_sets.
+ * @return boolean true if FD can be added to fd_set,
+ * boolean false otherwise.
+ */
+#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_ ((fd), \
+ (pset), \
+ FD_SETSIZE)
+
+/**
+ * Add FD to fd_set with specified FD_SETSIZE.
+ * @param fd the fd to add
+ * @param pset the valid pointer to fd_set.
+ * @param setsize the value of FD_SETSIZE.
+ * @note To work on W32 with value of FD_SETSIZE different from currently defined value,
+ * system definition of FD_SET() is not used.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET ((fd), \
+ (pset))
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \
+ do { \
+ u_int _i_ = 0; \
+ fd_set*const _s_ = (fd_set*) (pset); \
+ while ((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array [_i_])) {++_i_;} \
+ if ((_i_ == _s_->fd_count)) {_s_->fd_array [_s_->fd_count ++] = (fd);} \
+ } while (0)
+#endif
+
+/* MHD_SYS_select_ is wrapper macro for system select() function */
+#if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SYS_select_(n,r,w,e,t) select ((n),(r),(w),(e),(t))
+#else
+# define MHD_SYS_select_(n,r,w,e,t) \
+ ( ( (((void*) (r) == (void*) 0) || ((fd_set*) (r))->fd_count == 0) && \
+ (((void*) (w) == (void*) 0) || ((fd_set*) (w))->fd_count == 0) && \
+ (((void*) (e) == (void*) 0) || ((fd_set*) (e))->fd_count == 0) ) ? \
+ ( ((void*) (t) == (void*) 0) ? 0 : \
+ (Sleep (((struct timeval*) (t))->tv_sec * 1000 \
+ + ((struct timeval*) (t))->tv_usec / 1000), 0) ) : \
+ (select ((int) 0,(r),(w),(e),(t))) )
+#endif
+
+#if defined(HAVE_POLL)
+/* MHD_sys_poll_ is wrapper macro for system poll() function */
+# if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_sys_poll_ poll
+# else /* MHD_WINSOCK_SOCKETS */
+# define MHD_sys_poll_ WSAPoll
+# endif /* MHD_WINSOCK_SOCKETS */
+
+# ifdef POLLPRI
+# define MHD_POLLPRI_OR_ZERO POLLPRI
+# else /* ! POLLPRI */
+# define MHD_POLLPRI_OR_ZERO 0
+# endif /* ! POLLPRI */
+# ifdef POLLRDBAND
+# define MHD_POLLRDBAND_OR_ZERO POLLRDBAND
+# else /* ! POLLRDBAND */
+# define MHD_POLLRDBAND_OR_ZERO 0
+# endif /* ! POLLRDBAND */
+# ifdef POLLNVAL
+# define MHD_POLLNVAL_OR_ZERO POLLNVAL
+# else /* ! POLLNVAL */
+# define MHD_POLLNVAL_OR_ZERO 0
+# endif /* ! POLLNVAL */
+
+/* MHD_POLL_EVENTS_ERR_DISC is 'events' mask for errors and disconnect.
+ * Note: Out-of-band data is treated as error. */
+# if defined(_WIN32) && ! defined(__CYGWIN__)
+# define MHD_POLL_EVENTS_ERR_DISC POLLRDBAND
+# elif defined(__linux__)
+# define MHD_POLL_EVENTS_ERR_DISC POLLPRI
+# else /* ! __linux__ */
+# define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO \
+ | MHD_POLLRDBAND_OR_ZERO)
+# endif /* ! __linux__ */
+/* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect.
+ * Note: Out-of-band data is treated as error. */
+# define MHD_POLL_REVENTS_ERR_DISC \
+ (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
+ | POLLERR | POLLHUP)
+/* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors.
+ * Note: Out-of-band data is treated as error. */
+# define MHD_POLL_REVENTS_ERRROR \
+ (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
+ | POLLERR)
+#endif /* HAVE_POLL */
+
+#define MHD_SCKT_MISSING_ERR_CODE_ 31450
+
+#if defined(MHD_POSIX_SOCKETS)
+# if defined(EAGAIN)
+# define MHD_SCKT_EAGAIN_ EAGAIN
+# elif defined(EWOULDBLOCK)
+# define MHD_SCKT_EAGAIN_ EWOULDBLOCK
+# else /* !EAGAIN && !EWOULDBLOCK */
+# define MHD_SCKT_EAGAIN_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* !EAGAIN && !EWOULDBLOCK */
+# if defined(EWOULDBLOCK)
+# define MHD_SCKT_EWOULDBLOCK_ EWOULDBLOCK
+# elif defined(EAGAIN)
+# define MHD_SCKT_EWOULDBLOCK_ EAGAIN
+# else /* !EWOULDBLOCK && !EAGAIN */
+# define MHD_SCKT_EWOULDBLOCK_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* !EWOULDBLOCK && !EAGAIN */
+# ifdef EINTR
+# define MHD_SCKT_EINTR_ EINTR
+# else /* ! EINTR */
+# define MHD_SCKT_EINTR_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EINTR */
+# ifdef ECONNRESET
+# define MHD_SCKT_ECONNRESET_ ECONNRESET
+# else /* ! ECONNRESET */
+# define MHD_SCKT_ECONNRESET_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ECONNRESET */
+# ifdef ECONNABORTED
+# define MHD_SCKT_ECONNABORTED_ ECONNABORTED
+# else /* ! ECONNABORTED */
+# define MHD_SCKT_ECONNABORTED_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ECONNABORTED */
+# ifdef ENOTCONN
+# define MHD_SCKT_ENOTCONN_ ENOTCONN
+# else /* ! ENOTCONN */
+# define MHD_SCKT_ENOTCONN_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOTCONN */
+# ifdef EMFILE
+# define MHD_SCKT_EMFILE_ EMFILE
+# else /* ! EMFILE */
+# define MHD_SCKT_EMFILE_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EMFILE */
+# ifdef ENFILE
+# define MHD_SCKT_ENFILE_ ENFILE
+# else /* ! ENFILE */
+# define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENFILE */
+# ifdef ENOMEM
+# define MHD_SCKT_ENOMEM_ ENOMEM
+# else /* ! ENOMEM */
+# define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOMEM */
+# ifdef ENOBUFS
+# define MHD_SCKT_ENOBUFS_ ENOBUFS
+# else /* ! ENOBUFS */
+# define MHD_SCKT_ENOBUFS_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOBUFS */
+# ifdef EBADF
+# define MHD_SCKT_EBADF_ EBADF
+# else /* ! EBADF */
+# define MHD_SCKT_EBADF_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EBADF */
+# ifdef ENOTSOCK
+# define MHD_SCKT_ENOTSOCK_ ENOTSOCK
+# else /* ! ENOTSOCK */
+# define MHD_SCKT_ENOTSOCK_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOTSOCK */
+# ifdef EINVAL
+# define MHD_SCKT_EINVAL_ EINVAL
+# else /* ! EINVAL */
+# define MHD_SCKT_EINVAL_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EINVAL */
+# ifdef EFAULT
+# define MHD_SCKT_EFAUL_ EFAULT
+# else /* ! EFAULT */
+# define MHD_SCKT_EFAUL_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EFAULT */
+# ifdef ENOSYS
+# define MHD_SCKT_ENOSYS_ ENOSYS
+# else /* ! ENOSYS */
+# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOSYS */
+# ifdef ENOTSUP
+# define MHD_SCKT_ENOTSUP_ ENOTSUP
+# else /* ! ENOTSUP */
+# define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOTSUP */
+# ifdef EOPNOTSUPP
+# define MHD_SCKT_EOPNOTSUPP_ EOPNOTSUPP
+# else /* ! EOPNOTSUPP */
+# define MHD_SCKT_EOPNOTSUPP_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EOPNOTSUPP */
+# ifdef EACCES
+# define MHD_SCKT_EACCESS_ EACCES
+# else /* ! EACCES */
+# define MHD_SCKT_EACCESS_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EACCES */
+# ifdef ENETDOWN
+# define MHD_SCKT_ENETDOWN_ ENETDOWN
+# else /* ! ENETDOWN */
+# define MHD_SCKT_ENETDOWN_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENETDOWN */
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SCKT_EAGAIN_ WSAEWOULDBLOCK
+# define MHD_SCKT_EWOULDBLOCK_ WSAEWOULDBLOCK
+# define MHD_SCKT_EINTR_ WSAEINTR
+# define MHD_SCKT_ECONNRESET_ WSAECONNRESET
+# define MHD_SCKT_ECONNABORTED_ WSAECONNABORTED
+# define MHD_SCKT_ENOTCONN_ WSAENOTCONN
+# define MHD_SCKT_EMFILE_ WSAEMFILE
+# define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_
+# define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_
+# define MHD_SCKT_ENOBUFS_ WSAENOBUFS
+# define MHD_SCKT_EBADF_ WSAEBADF
+# define MHD_SCKT_ENOTSOCK_ WSAENOTSOCK
+# define MHD_SCKT_EINVAL_ WSAEINVAL
+# define MHD_SCKT_EFAUL_ WSAEFAULT
+# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
+# define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_
+# define MHD_SCKT_EOPNOTSUPP_ WSAEOPNOTSUPP
+# define MHD_SCKT_EACCESS_ WSAEACCES
+# define MHD_SCKT_ENETDOWN_ WSAENETDOWN
+#endif
+
+/**
+ * MHD_socket_error_ return system native error code for last socket error.
+ * @return system error code for last socket error.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_socket_get_error_() (errno)
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_get_error_() WSAGetLastError ()
+#endif
+
+#ifdef MHD_WINSOCK_SOCKETS
+/* POSIX-W32 sockets compatibility functions */
+
+/**
+ * Return pointer to string description of specified WinSock error
+ * @param err the WinSock error code.
+ * @return pointer to string description of specified WinSock error.
+ */
+const char*MHD_W32_strerror_winsock_ (int err);
+
+#endif /* MHD_WINSOCK_SOCKETS */
+
+/* MHD_socket_last_strerr_ is description string of specified socket error code */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_socket_strerr_(err) strerror ((err))
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_ ((err))
+#endif
+
+/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
+ * description string of last socket error (W32) */
+#define MHD_socket_last_strerr_() MHD_socket_strerr_ (MHD_socket_get_error_ ())
+
+/**
+ * MHD_socket_fset_error_() set socket system native error code.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_socket_fset_error_(err) (errno = (err))
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_fset_error_(err) (WSASetLastError ((err)))
+#endif
+
+/**
+ * MHD_socket_try_set_error_() set socket system native error code if
+ * specified code is defined on system.
+ * @return non-zero if specified @a err code is defined on system
+ * and error was set;
+ * zero if specified @a err code is not defined on system
+ * and error was not set.
+ */
+#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \
+ (MHD_socket_fset_error_ ((err)), ! 0) : \
+ 0)
+
+/**
+ * MHD_socket_set_error_() set socket system native error code to
+ * specified code or replacement code if specified code is not
+ * defined on system.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# if defined(ENOSYS)
+# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
+ (errno = ENOSYS) : (errno = (err)) )
+# elif defined(EOPNOTSUPP)
+# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
+ (errno = EOPNOTSUPP) : (errno = \
+ (err)) )
+# elif defined (EFAULT)
+# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
+ (errno = EFAULT) : (errno = (err)) )
+# elif defined (EINVAL)
+# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
+ (errno = EINVAL) : (errno = (err)) )
+# else /* !EOPNOTSUPP && !EFAULT && !EINVAL */
+# warning \
+ No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
+# define MHD_socket_set_error_(err) (errno = (err))
+# endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
+ (WSASetLastError ((WSAEOPNOTSUPP))) : \
+ (WSASetLastError ((err))) )
+#endif
+
+/**
+ * Check whether given socket error is equal to specified system
+ * native MHD_SCKT_E*_ code.
+ * If platform don't have specific error code, result is
+ * always boolean false.
+ * @return boolean true if @a code is real error code and
+ * @a err equals to MHD_SCKT_E*_ @a code;
+ * boolean false otherwise
+ */
+#define MHD_SCKT_ERR_IS_(err,code) ( (MHD_SCKT_MISSING_ERR_CODE_ != (code)) && \
+ ((code) == (err)) )
+
+/**
+ * Check whether last socket error is equal to specified system
+ * native MHD_SCKT_E*_ code.
+ * If platform don't have specific error code, result is
+ * always boolean false.
+ * @return boolean true if @a code is real error code and
+ * last socket error equals to MHD_SCKT_E*_ @a code;
+ * boolean false otherwise
+ */
+#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_ (MHD_socket_get_error_ (), \
+ (code))
+
+/* Specific error code checks */
+
+/**
+ * Check whether given socket error is equal to system's
+ * socket error codes for EINTR.
+ * @return boolean true if @a err is equal to sockets' EINTR code;
+ * boolean false otherwise.
+ */
+#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EINTR_)
+
+/**
+ * Check whether given socket error is equal to system's
+ * socket error codes for EAGAIN or EWOULDBLOCK.
+ * @return boolean true if @a err is equal to sockets' EAGAIN or EWOULDBLOCK codes;
+ * boolean false otherwise.
+ */
+#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_
+# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EAGAIN_)
+#else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
+# define MHD_SCKT_ERR_IS_EAGAIN_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EAGAIN_) || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EWOULDBLOCK_) )
+#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
+
+/**
+ * Check whether given socket error is any kind of "low resource" error.
+ * @return boolean true if @a err is any kind of "low resource" error,
+ * boolean false otherwise.
+ */
+#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EMFILE_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENFILE_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENOMEM_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENOBUFS_) )
+
+/**
+ * Check whether is given socket error is type of "incoming connection
+ * was disconnected before 'accept()' is called".
+ * @return boolean true is @a err match described socket error code,
+ * boolean false otherwise.
+ */
+#if defined(MHD_POSIX_SOCKETS)
+# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNABORTED_)
+#elif defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNRESET_)
+#endif
+
+/**
+ * Check whether is given socket error is type of "connection was terminated
+ * by remote side".
+ * @return boolean true is @a err match described socket error code,
+ * boolean false otherwise.
+ */
+#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNRESET_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNABORTED_))
+
+/* Specific error code set */
+
+/**
+ * Set socket's error code to ENOMEM or equivalent if ENOMEM is not
+ * available on platform.
+ */
+#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOMEM_)
+#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOBUFS_)
+#else
+# warning \
+ No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOMEM_)
+#endif
+
+/* Socket functions */
+
+#if defined(AF_LOCAL)
+# define MHD_SCKT_LOCAL AF_LOCAL
+#elif defined(AF_UNIX)
+# define MHD_SCKT_LOCAL AF_UNIX
+#endif /* AF_UNIX */
+
+#if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL)
+# define MHD_socket_pair_(fdarr) (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM, 0, \
+ (fdarr)))
+# if defined(HAVE_SOCK_NONBLOCK)
+# define MHD_socket_pair_nblk_(fdarr) (! socketpair (MHD_SCKT_LOCAL, \
+ SOCK_STREAM \
+ | SOCK_NONBLOCK, 0, \
+ (fdarr)))
+# endif /* HAVE_SOCK_NONBLOCK*/
+#elif defined(MHD_WINSOCK_SOCKETS)
+/**
+ * Create pair of mutually connected TCP/IP sockets on loopback address
+ * @param sockets_pair array to receive resulted sockets
+ * @param non_blk if set to non-zero value, sockets created in non-blocking mode
+ * otherwise sockets will be in blocking mode
+ * @return non-zero if succeeded, zero otherwise
+ */
+int MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk);
+
+# define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_ ((fdarr), 0)
+# define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_ ((fdarr), 1)
+#endif
+
+/**
+ * Add @a fd to the @a set. If @a fd is
+ * greater than @a max_fd, set @a max_fd to @a fd.
+ *
+ * @param fd file descriptor to add to the @a set
+ * @param set set to modify
+ * @param max_fd maximum value to potentially update
+ * @param fd_setsize value of FD_SETSIZE
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_add_to_fd_set_ (MHD_socket fd,
+ fd_set *set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize);
+
+
+/**
+ * Change socket options to be non-blocking.
+ *
+ * @param sock socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_socket_nonblocking_ (MHD_socket sock);
+
+
+/**
+ * Change socket options to be non-inheritable.
+ *
+ * @param sock socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ * @warning Does not set socket error on W32.
+ */
+int
+MHD_socket_noninheritable_ (MHD_socket sock);
+
+
+#if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE)
+static const int _MHD_socket_int_one = 1;
+/**
+ * Change socket options to no signal on remote disconnect.
+ *
+ * @param sock socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+# define MHD_socket_nosignal_(sock) \
+ (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \
+ sizeof(_MHD_socket_int_one)))
+#endif /* SOL_SOCKET && SO_NOSIGPIPE */
+
+/**
+ * Create a listen socket, with noninheritable flag if possible.
+ *
+ * @param pf protocol family to use
+ * @return created socket or MHD_INVALID_SOCKET in case of errors
+ */
+MHD_socket
+MHD_socket_create_listen_ (int pf);
+
+#endif /* ! MHD_SOCKETS_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_str.c
^
|
@@ -0,0 +1,788 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015, 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/mhd_str.c
+ * @brief Functions implementations for string manipulating
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_str.h"
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
+
+#include "mhd_limits.h"
+
+#ifdef MHD_FAVOR_SMALL_CODE
+#ifdef _MHD_static_inline
+#undef _MHD_static_inline
+#endif /* _MHD_static_inline */
+/* Do not force inlining and do not use macro functions, use normal static
+ functions instead.
+ This may give more flexibility for size optimizations. */
+#define _MHD_static_inline static
+#ifndef INLINE_FUNC
+#define INLINE_FUNC 1
+#endif /* !INLINE_FUNC */
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+/*
+ * Block of functions/macros that use US-ASCII charset as required by HTTP
+ * standards. Not affected by current locale settings.
+ */
+
+#ifdef INLINE_FUNC
+
+#if 0 /* Disable unused functions. */
+/**
+ * Check whether character is lower case letter in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is lower case letter, zero otherwise
+ */
+_MHD_static_inline bool
+isasciilower (char c)
+{
+ return (c >= 'a') && (c <= 'z');
+}
+
+
+#endif /* Disable unused functions. */
+
+
+/**
+ * Check whether character is upper case letter in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is upper case letter, zero otherwise
+ */
+_MHD_static_inline bool
+isasciiupper (char c)
+{
+ return (c >= 'A') && (c <= 'Z');
+}
+
+
+#if 0 /* Disable unused functions. */
+/**
+ * Check whether character is letter in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is letter in US-ASCII, zero otherwise
+ */
+_MHD_static_inline bool
+isasciialpha (char c)
+{
+ return isasciilower (c) || isasciiupper (c);
+}
+
+
+#endif /* Disable unused functions. */
+
+
+/**
+ * Check whether character is decimal digit in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is decimal digit, zero otherwise
+ */
+_MHD_static_inline bool
+isasciidigit (char c)
+{
+ return (c >= '0') && (c <= '9');
+}
+
+
+#if 0 /* Disable unused functions. */
+/**
+ * Check whether character is hexadecimal digit in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is decimal digit, zero otherwise
+ */
+_MHD_static_inline bool
+isasciixdigit (char c)
+{
+ return isasciidigit (c) ||
+ ( (c >= 'A') && (c <= 'F') ) ||
+ ( (c >= 'a') && (c <= 'f') );
+}
+
+
+/**
+ * Check whether character is decimal digit or letter in US-ASCII
+ *
+ * @param c character to check
+ * @return non-zero if character is decimal digit or letter, zero otherwise
+ */
+_MHD_static_inline bool
+isasciialnum (char c)
+{
+ return isasciialpha (c) || isasciidigit (c);
+}
+
+
+#endif /* Disable unused functions. */
+
+
+/**
+ * Convert US-ASCII character to lower case.
+ * If character is upper case letter in US-ASCII than it's converted to lower
+ * case analog. If character is NOT upper case letter than it's returned
+ * unmodified.
+ *
+ * @param c character to convert
+ * @return converted to lower case character
+ */
+_MHD_static_inline char
+toasciilower (char c)
+{
+ return isasciiupper (c) ? (c - 'A' + 'a') : c;
+}
+
+
+#if 0 /* Disable unused functions. */
+/**
+ * Convert US-ASCII character to upper case.
+ * If character is lower case letter in US-ASCII than it's converted to upper
+ * case analog. If character is NOT lower case letter than it's returned
+ * unmodified.
+ *
+ * @param c character to convert
+ * @return converted to upper case character
+ */
+_MHD_static_inline char
+toasciiupper (char c)
+{
+ return isasciilower (c) ? (c - 'a' + 'A') : c;
+}
+
+
+#endif /* Disable unused functions. */
+
+
+#if defined(MHD_FAVOR_SMALL_CODE) /* Used only in MHD_str_to_uvalue_n_() */
+/**
+ * Convert US-ASCII decimal digit to its value.
+ *
+ * @param c character to convert
+ * @return value of decimal digit or -1 if @ c is not decimal digit
+ */
+_MHD_static_inline int
+todigitvalue (char c)
+{
+ if (isasciidigit (c))
+ return (unsigned char) (c - '0');
+
+ return -1;
+}
+
+
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+
+/**
+ * Convert US-ASCII hexadecimal digit to its value.
+ *
+ * @param c character to convert
+ * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
+ */
+_MHD_static_inline int
+toxdigitvalue (char c)
+{
+ if (isasciidigit (c))
+ return (unsigned char) (c - '0');
+ if ( (c >= 'A') && (c <= 'F') )
+ return (unsigned char) (c - 'A' + 10);
+ if ( (c >= 'a') && (c <= 'f') )
+ return (unsigned char) (c - 'a' + 10);
+
+ return -1;
+}
+
+
+#else /* !INLINE_FUNC */
+
+
+/**
+ * Checks whether character is lower case letter in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is lower case letter,
+ * boolean false otherwise
+ */
+#define isasciilower(c) (((char) (c)) >= 'a' && ((char) (c)) <= 'z')
+
+
+/**
+ * Checks whether character is upper case letter in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is upper case letter,
+ * boolean false otherwise
+ */
+#define isasciiupper(c) (((char) (c)) >= 'A' && ((char) (c)) <= 'Z')
+
+
+/**
+ * Checks whether character is letter in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is letter, boolean false
+ * otherwise
+ */
+#define isasciialpha(c) (isasciilower (c) || isasciiupper (c))
+
+
+/**
+ * Check whether character is decimal digit in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is decimal digit, boolean false
+ * otherwise
+ */
+#define isasciidigit(c) (((char) (c)) >= '0' && ((char) (c)) <= '9')
+
+
+/**
+ * Check whether character is hexadecimal digit in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is hexadecimal digit,
+ * boolean false otherwise
+ */
+#define isasciixdigit(c) (isasciidigit ((c)) || \
+ (((char) (c)) >= 'A' && ((char) (c)) <= 'F') || \
+ (((char) (c)) >= 'a' && ((char) (c)) <= 'f') )
+
+
+/**
+ * Check whether character is decimal digit or letter in US-ASCII
+ *
+ * @param c character to check
+ * @return boolean true if character is decimal digit or letter,
+ * boolean false otherwise
+ */
+#define isasciialnum(c) (isasciialpha (c) || isasciidigit (c))
+
+
+/**
+ * Convert US-ASCII character to lower case.
+ * If character is upper case letter in US-ASCII than it's converted to lower
+ * case analog. If character is NOT upper case letter than it's returned
+ * unmodified.
+ *
+ * @param c character to convert
+ * @return converted to lower case character
+ */
+#define toasciilower(c) ((isasciiupper (c)) ? (((char) (c)) - 'A' + 'a') : \
+ ((char) (c)))
+
+
+/**
+ * Convert US-ASCII character to upper case.
+ * If character is lower case letter in US-ASCII than it's converted to upper
+ * case analog. If character is NOT lower case letter than it's returned
+ * unmodified.
+ *
+ * @param c character to convert
+ * @return converted to upper case character
+ */
+#define toasciiupper(c) ((isasciilower (c)) ? (((char) (c)) - 'a' + 'A') : \
+ ((char) (c)))
+
+
+/**
+ * Convert US-ASCII decimal digit to its value.
+ *
+ * @param c character to convert
+ * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
+ */
+#define todigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
+ (int) (-1))
+
+
+/**
+ * Convert US-ASCII hexadecimal digit to its value.
+ * @param c character to convert
+ * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
+ */
+#define toxdigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
+ ( (((char) (c)) >= 'A' && ((char) (c)) <= 'F') ? \
+ (int) (((unsigned char) (c)) - 'A' + 10) : \
+ ( (((char) (c)) >= 'a' && ((char) (c)) <= 'f') ? \
+ (int) (((unsigned char) (c)) - 'a' + 10) : \
+ (int) (-1) )))
+#endif /* !INLINE_FUNC */
+
+
+#ifndef MHD_FAVOR_SMALL_CODE
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters.
+ *
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+int
+MHD_str_equal_caseless_ (const char *str1,
+ const char *str2)
+{
+ while (0 != (*str1))
+ {
+ const char c1 = *str1;
+ const char c2 = *str2;
+ if ( (c1 != c2) &&
+ (toasciilower (c1) != toasciilower (c2)) )
+ return 0;
+ str1++;
+ str2++;
+ }
+ return 0 == (*str2);
+}
+
+
+#endif /* ! MHD_FAVOR_SMALL_CODE */
+
+
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters and
+ * checking not more than @a maxlen characters.
+ * Compares up to first terminating null character, but not more than
+ * first @a maxlen characters.
+ *
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @param maxlen maximum number of characters to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+int
+MHD_str_equal_caseless_n_ (const char *const str1,
+ const char *const str2,
+ size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i < maxlen; ++i)
+ {
+ const char c1 = str1[i];
+ const char c2 = str2[i];
+ if (0 == c2)
+ return 0 == c1;
+ if ( (c1 != c2) &&
+ (toasciilower (c1) != toasciilower (c2)) )
+ return 0;
+ }
+ return ! 0;
+}
+
+
+/**
+ * Check whether @a str has case-insensitive @a token.
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Match succeed if substring between start, end (of string) or comma
+ * contains only case-insensitive token and optional spaces and tabs.
+ * @warning token must not contain null-charters except optional
+ * terminating null-character.
+ * @param str the string to check
+ * @param token the token to find
+ * @param token_len length of token, not including optional terminating
+ * null-character.
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+bool
+MHD_str_has_token_caseless_ (const char *str,
+ const char *const token,
+ size_t token_len)
+{
+ if (0 == token_len)
+ return false;
+
+ while (0 != *str)
+ {
+ size_t i;
+ /* Skip all whitespaces and empty tokens. */
+ while (' ' == *str || '\t' == *str || ',' == *str)
+ str++;
+
+ /* Check for token match. */
+ i = 0;
+ while (1)
+ {
+ const char sc = *(str++);
+ const char tc = token[i++];
+
+ if (0 == sc)
+ return false;
+ if ( (sc != tc) &&
+ (toasciilower (sc) != toasciilower (tc)) )
+ break;
+ if (i >= token_len)
+ {
+ /* Check whether substring match token fully or
+ * has additional unmatched chars at tail. */
+ while (' ' == *str || '\t' == *str)
+ str++;
+ /* End of (sub)string? */
+ if ((0 == *str) || (',' == *str) )
+ return true;
+ /* Unmatched chars at end of substring. */
+ break;
+ }
+ }
+ /* Find next substring. */
+ while (0 != *str && ',' != *str)
+ str++;
+ }
+ return false;
+}
+
+
+#ifndef MHD_FAVOR_SMALL_CODE
+/* Use individual function for each case */
+
+/**
+ * Convert decimal US-ASCII digits in string to number in uint64_t.
+ * Conversion stopped at first non-digit character.
+ *
+ * @param str string to convert
+ * @param[out] out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uint64_ (const char *str,
+ uint64_t *out_val)
+{
+ const char *const start = str;
+ uint64_t res;
+
+ if (! str || ! out_val || ! isasciidigit (str[0]))
+ return 0;
+
+ res = 0;
+ do
+ {
+ const int digit = (unsigned char) (*str) - '0';
+ if ( (res > (UINT64_MAX / 10)) ||
+ ( (res == (UINT64_MAX / 10)) &&
+ ((uint64_t) digit > (UINT64_MAX % 10)) ) )
+ return 0;
+
+ res *= 10;
+ res += digit;
+ str++;
+ } while (isasciidigit (*str));
+
+ *out_val = res;
+ return str - start;
+}
+
+
+/**
+ * Convert not more then @a maxlen decimal US-ASCII digits in string to
+ * number in uint64_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ *
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param[out] out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uint64_n_ (const char *str,
+ size_t maxlen,
+ uint64_t *out_val)
+{
+ uint64_t res;
+ size_t i;
+
+ if (! str || ! maxlen || ! out_val || ! isasciidigit (str[0]))
+ return 0;
+
+ res = 0;
+ i = 0;
+ do
+ {
+ const int digit = (unsigned char) str[i] - '0';
+
+ if ( (res > (UINT64_MAX / 10)) ||
+ ( (res == (UINT64_MAX / 10)) &&
+ ((uint64_t) digit > (UINT64_MAX % 10)) ) )
+ return 0;
+
+ res *= 10;
+ res += digit;
+ i++;
+ } while ( (i < maxlen) &&
+ isasciidigit (str[i]) );
+
+ *out_val = res;
+ return i;
+}
+
+
+/**
+ * Convert hexadecimal US-ASCII digits in string to number in uint32_t.
+ * Conversion stopped at first non-digit character.
+ *
+ * @param str string to convert
+ * @param[out] out_val pointer to uint32_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint32_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint32_ (const char *str,
+ uint32_t *out_val)
+{
+ const char *const start = str;
+ uint32_t res;
+ int digit;
+
+ if (! str || ! out_val)
+ return 0;
+
+ res = 0;
+ digit = toxdigitvalue (*str);
+ while (digit >= 0)
+ {
+ if ( (res < (UINT32_MAX / 16)) ||
+ ((res == (UINT32_MAX / 16)) && ( (uint32_t) digit <= (UINT32_MAX
+ % 16)) ) )
+ {
+ res *= 16;
+ res += digit;
+ }
+ else
+ return 0;
+ str++;
+ digit = toxdigitvalue (*str);
+ }
+
+ if (str - start > 0)
+ *out_val = res;
+ return str - start;
+}
+
+
+/**
+ * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
+ * to number in uint32_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ *
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param[out] out_val pointer to uint32_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint32_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint32_n_ (const char *str,
+ size_t maxlen,
+ uint32_t *out_val)
+{
+ size_t i;
+ uint32_t res;
+ int digit;
+ if (! str || ! out_val)
+ return 0;
+
+ res = 0;
+ i = 0;
+ while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
+ {
+ if ( (res > (UINT32_MAX / 16)) ||
+ ((res == (UINT32_MAX / 16)) && ( (uint32_t) digit > (UINT32_MAX
+ % 16)) ) )
+ return 0;
+
+ res *= 16;
+ res += digit;
+ i++;
+ }
+
+ if (i)
+ *out_val = res;
+ return i;
+}
+
+
+/**
+ * Convert hexadecimal US-ASCII digits in string to number in uint64_t.
+ * Conversion stopped at first non-digit character.
+ *
+ * @param str string to convert
+ * @param[out] out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint64_ (const char *str,
+ uint64_t *out_val)
+{
+ const char *const start = str;
+ uint64_t res;
+ int digit;
+ if (! str || ! out_val)
+ return 0;
+
+ res = 0;
+ digit = toxdigitvalue (*str);
+ while (digit >= 0)
+ {
+ if ( (res < (UINT64_MAX / 16)) ||
+ ((res == (UINT64_MAX / 16)) && ( (uint64_t) digit <= (UINT64_MAX
+ % 16)) ) )
+ {
+ res *= 16;
+ res += digit;
+ }
+ else
+ return 0;
+ str++;
+ digit = toxdigitvalue (*str);
+ }
+
+ if (str - start > 0)
+ *out_val = res;
+ return str - start;
+}
+
+
+/**
+ * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
+ * to number in uint64_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ *
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param[out] out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint64_n_ (const char *str,
+ size_t maxlen,
+ uint64_t *out_val)
+{
+ size_t i;
+ uint64_t res;
+ int digit;
+ if (! str || ! out_val)
+ return 0;
+
+ res = 0;
+ i = 0;
+ while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
+ {
+ if ( (res > (UINT64_MAX / 16)) ||
+ ((res == (UINT64_MAX / 16)) && ( (uint64_t) digit > (UINT64_MAX
+ % 16)) ) )
+ return 0;
+
+ res *= 16;
+ res += digit;
+ i++;
+ }
+
+ if (i)
+ *out_val = res;
+ return i;
+}
+
+
+#else /* MHD_FAVOR_SMALL_CODE */
+
+/**
+ * Generic function for converting not more then @a maxlen
+ * hexadecimal or decimal US-ASCII digits in string to number.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ * To be used only within macro.
+ *
+ * @param str the string to convert
+ * @param maxlen the maximum number of characters to process
+ * @param out_val the pointer to variable to store result of conversion
+ * @param val_size the size of variable pointed by @a out_val, in bytes, 4 or 8
+ * @param max_val the maximum decoded number
+ * @param base the numeric base, 10 or 16
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then @max_val, @val_size is not 16/32 or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uvalue_n_ (const char *str,
+ size_t maxlen,
+ void *out_val,
+ size_t val_size,
+ uint64_t max_val,
+ int base)
+{
+ size_t i;
+ uint64_t res;
+ int digit;
+ const uint64_t max_v_div_b = max_val / base;
+ const uint64_t max_v_mod_b = max_val % base;
+ /* 'digit->value' must be function, not macro */
+ int (*const dfunc)(char) = (base == 16) ?
+ toxdigitvalue : todigitvalue;
+
+ if (! str || ! out_val ||
+ ((base != 16) && (base != 10)) )
+ return 0;
+
+ res = 0;
+ i = 0;
+ while (maxlen > i && 0 <= (digit = dfunc (str[i])))
+ {
+ if ( ((max_v_div_b) < res) ||
+ (( (max_v_div_b) == res) && ( (max_v_mod_b) < (uint64_t) digit) ) )
+ return 0;
+
+ res *= base;
+ res += digit;
+ i++;
+ }
+
+ if (i)
+ {
+ if (8 == val_size)
+ *(uint64_t*) out_val = res;
+ else if (4 == val_size)
+ *(uint32_t*) out_val = (uint32_t) res;
+ else
+ return 0;
+ }
+ return i;
+}
+
+
+#endif /* MHD_FAVOR_SMALL_CODE */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_str.h
^
|
@@ -0,0 +1,276 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015, 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/mhd_str.h
+ * @brief Header for string manipulating helpers
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_STR_H
+#define MHD_STR_H 1
+
+#include "mhd_options.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif /* HAVE_STDBOOL_H */
+
+#ifdef MHD_FAVOR_SMALL_CODE
+#include "mhd_limits.h"
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+#ifndef MHD_STATICSTR_LEN_
+/**
+ * Determine length of static string / macro strings at compile time.
+ */
+#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
+#endif /* ! MHD_STATICSTR_LEN_ */
+
+/*
+ * Block of functions/macros that use US-ASCII charset as required by HTTP
+ * standards. Not affected by current locale settings.
+ */
+
+#ifndef MHD_FAVOR_SMALL_CODE
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters.
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+int
+MHD_str_equal_caseless_ (const char *str1,
+ const char *str2);
+
+#else /* MHD_FAVOR_SMALL_CODE */
+/* Reuse MHD_str_equal_caseless_n_() to reduce size */
+#define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_ ((s1),(s2), \
+ SIZE_MAX)
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters and
+ * checking not more than @a maxlen characters.
+ * Compares up to first terminating null character, but not more than
+ * first @a maxlen characters.
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @param maxlen maximum number of characters to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+int
+MHD_str_equal_caseless_n_ (const char *const str1,
+ const char *const str2,
+ size_t maxlen);
+
+
+/**
+ * Check whether @a str has case-insensitive @a token.
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Match succeed if substring between start, end of string or comma
+ * contains only case-insensitive token and optional spaces and tabs.
+ * @warning token must not contain null-charters except optional
+ * terminating null-character.
+ * @param str the string to check
+ * @param token the token to find
+ * @param token_len length of token, not including optional terminating
+ * null-character.
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+bool
+MHD_str_has_token_caseless_ (const char *str,
+ const char *const token,
+ size_t token_len);
+
+/**
+ * Check whether @a str has case-insensitive static @a tkn.
+ * Token could be surrounded by spaces and tabs and delimited by comma.
+ * Match succeed if substring between start, end of string or comma
+ * contains only case-insensitive token and optional spaces and tabs.
+ * @warning tkn must be static string
+ * @param str the string to check
+ * @param tkn the static string of token to find
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+#define MHD_str_has_s_token_caseless_(str,tkn) \
+ MHD_str_has_token_caseless_ ((str),(tkn),MHD_STATICSTR_LEN_ (tkn))
+
+#ifndef MHD_FAVOR_SMALL_CODE
+/* Use individual function for each case to improve speed */
+
+/**
+ * Convert decimal US-ASCII digits in string to number in uint64_t.
+ * Conversion stopped at first non-digit character.
+ * @param str string to convert
+ * @param out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uint64_ (const char *str,
+ uint64_t *out_val);
+
+/**
+ * Convert not more then @a maxlen decimal US-ASCII digits in string to
+ * number in uint64_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uint64_n_ (const char *str,
+ size_t maxlen,
+ uint64_t *out_val);
+
+
+/**
+ * Convert hexadecimal US-ASCII digits in string to number in uint32_t.
+ * Conversion stopped at first non-digit character.
+ * @param str string to convert
+ * @param out_val pointer to uint32_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint32_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint32_ (const char *str,
+ uint32_t *out_val);
+
+
+/**
+ * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
+ * to number in uint32_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param out_val pointer to uint32_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint32_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint32_n_ (const char *str,
+ size_t maxlen,
+ uint32_t *out_val);
+
+
+/**
+ * Convert hexadecimal US-ASCII digits in string to number in uint64_t.
+ * Conversion stopped at first non-digit character.
+ * @param str string to convert
+ * @param out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint64_ (const char *str,
+ uint64_t *out_val);
+
+
+/**
+ * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
+ * to number in uint64_t.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ * @param str string to convert
+ * @param maxlen maximum number of characters to process
+ * @param out_val pointer to uint64_t to store result of conversion
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then possible to store in uint64_t or @a out_val is NULL
+ */
+size_t
+MHD_strx_to_uint64_n_ (const char *str,
+ size_t maxlen,
+ uint64_t *out_val);
+
+#else /* MHD_FAVOR_SMALL_CODE */
+/* Use one universal function and macros to reduce size */
+
+/**
+ * Generic function for converting not more then @a maxlen
+ * hexadecimal or decimal US-ASCII digits in string to number.
+ * Conversion stopped at first non-digit character or after @a maxlen
+ * digits.
+ * To be used only within macro.
+ * @param str the string to convert
+ * @param maxlen the maximum number of characters to process
+ * @param out_val the pointer to uint64_t to store result of conversion
+ * @param val_size the size of variable pointed by @a out_val
+ * @param max_val the maximum decoded number
+ * @param base the numeric base, 10 or 16
+ * @return non-zero number of characters processed on succeed,
+ * zero if no digit is found, resulting value is larger
+ * then @ max_val or @a out_val is NULL
+ */
+size_t
+MHD_str_to_uvalue_n_ (const char *str,
+ size_t maxlen,
+ void *out_val,
+ size_t val_size,
+ uint64_t max_val,
+ int base);
+
+#define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,10)
+
+#define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,10)
+
+#define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(size_t),SIZE_MAX, \
+ 16)
+
+#define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(size_t), \
+ SIZE_MAX,16)
+
+#define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint32_t), \
+ UINT32_MAX,16)
+
+#define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint32_t), \
+ UINT32_MAX,16)
+
+#define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,16)
+
+#define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,16)
+
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+#endif /* MHD_STR_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_threads.c
^
|
@@ -0,0 +1,368 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_threads.c
+ * @brief Implementation for thread functions
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_threads.h"
+#ifdef MHD_USE_W32_THREADS
+#include "mhd_limits.h"
+#include <process.h>
+#endif
+#ifdef MHD_USE_THREAD_NAME_
+#include <stdlib.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif /* HAVE_PTHREAD_NP_H */
+#endif /* MHD_USE_THREAD_NAME_ */
+#include <errno.h>
+
+
+#ifndef MHD_USE_THREAD_NAME_
+
+#define MHD_set_thread_name_(t, n) (void)
+#define MHD_set_cur_thread_name_(n) (void)
+
+#else /* MHD_USE_THREAD_NAME_ */
+
+#if defined(MHD_USE_POSIX_THREADS)
+#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
+# define MHD_USE_THREAD_ATTR_SETNAME 1
+#endif \
+ /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */
+
+#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
+ defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \
+ || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
+
+/**
+ * Set thread name
+ *
+ * @param thread_id ID of thread
+ * @param thread_name name to set
+ * @return non-zero on success, zero otherwise
+ */
+static int
+MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+ const char *thread_name)
+{
+ if (NULL == thread_name)
+ return 0;
+
+#if defined(HAVE_PTHREAD_SETNAME_NP_GNU)
+ return ! pthread_setname_np (thread_id, thread_name);
+#elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD)
+ /* FreeBSD and OpenBSD use different name and void return type */
+ pthread_set_name_np (thread_id, thread_name);
+ return ! 0;
+#elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
+ /* NetBSD use 3 arguments: second argument is string in printf-like format,
+ * third argument is single argument for printf;
+ * OSF1 use 3 arguments too, but last one always must be zero (NULL).
+ * MHD doesn't use '%' in thread names, so both form are used in same way.
+ */return ! pthread_setname_np (thread_id, thread_name, 0);
+#endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */
+}
+
+
+#ifndef __QNXNTO__
+/**
+ * Set current thread name
+ * @param n name to set
+ * @return non-zero on success, zero otherwise
+ */
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (pthread_self (),(n))
+#else /* __QNXNTO__ */
+/* Special case for QNX Neutrino - using zero for thread ID sets name faster. */
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (0,(n))
+#endif /* __QNXNTO__ */
+#elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN)
+
+/**
+ * Set current thread name
+ * @param n name to set
+ * @return non-zero on success, zero otherwise
+ */
+#define MHD_set_cur_thread_name_(n) (! (pthread_setname_np ((n))))
+#endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */
+
+#elif defined(MHD_USE_W32_THREADS)
+#ifndef _MSC_FULL_VER
+/* Thread name available only for VC-compiler */
+#else /* _MSC_FULL_VER */
+/**
+ * Set thread name
+ *
+ * @param thread_id ID of thread, -1 for current thread
+ * @param thread_name name to set
+ * @return non-zero on success, zero otherwise
+ */
+static int
+MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+ const char *thread_name)
+{
+ static const DWORD VC_SETNAME_EXC = 0x406D1388;
+#pragma pack(push,8)
+ struct thread_info_struct
+ {
+ DWORD type; /* Must be 0x1000. */
+ LPCSTR name; /* Pointer to name (in user address space). */
+ DWORD ID; /* Thread ID (-1 = caller thread). */
+ DWORD flags; /* Reserved for future use, must be zero. */
+ } thread_info;
+#pragma pack(pop)
+
+ if (NULL == thread_name)
+ return 0;
+
+ thread_info.type = 0x1000;
+ thread_info.name = thread_name;
+ thread_info.ID = thread_id;
+ thread_info.flags = 0;
+
+ __try
+ { /* This exception is intercepted by debugger */
+ RaiseException (VC_SETNAME_EXC,
+ 0,
+ sizeof (thread_info) / sizeof(ULONG_PTR),
+ (ULONG_PTR *) &thread_info);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {}
+
+ return ! 0;
+}
+
+
+/**
+ * Set current thread name
+ * @param n name to set
+ * @return non-zero on success, zero otherwise
+ */
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (-1,(n))
+#endif /* _MSC_FULL_VER */
+#endif /* MHD_USE_W32_THREADS */
+
+#endif /* MHD_USE_THREAD_NAME_ */
+
+
+/**
+ * Create a thread and set the attributes according to our options.
+ *
+ * @param thread handle to initialize
+ * @param stack_size size of stack for new thread, 0 for default
+ * @param start_routine main function of thread
+ * @param arg argument for start_routine
+ * @return non-zero on success; zero otherwise (with errno set)
+ */
+int
+MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
+ size_t stack_size,
+ MHD_THREAD_START_ROUTINE_ start_routine,
+ void *arg)
+{
+#if defined(MHD_USE_POSIX_THREADS)
+ int res;
+
+ if (0 != stack_size)
+ {
+ pthread_attr_t attr;
+ res = pthread_attr_init (&attr);
+ if (0 == res)
+ {
+ res = pthread_attr_setstacksize (&attr,
+ stack_size);
+ if (0 == res)
+ res = pthread_create (&(thread->handle),
+ &attr,
+ start_routine,
+ arg);
+ pthread_attr_destroy (&attr);
+ }
+ }
+ else
+ res = pthread_create (&(thread->handle),
+ NULL,
+ start_routine,
+ arg);
+
+ if (0 != res)
+ errno = res;
+
+ return ! res;
+#elif defined(MHD_USE_W32_THREADS)
+#if SIZE_MAX != UINT_MAX
+ if (stack_size > UINT_MAX)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+#endif /* SIZE_MAX != UINT_MAX */
+
+ thread->handle = (MHD_thread_handle_)
+ _beginthreadex (NULL,
+ (unsigned int) stack_size,
+ start_routine,
+ arg,
+ 0,
+ NULL);
+
+ if ((MHD_thread_handle_) - 1 == thread->handle)
+ return 0;
+
+ return ! 0;
+#endif
+}
+
+
+#ifdef MHD_USE_THREAD_NAME_
+
+#ifndef MHD_USE_THREAD_ATTR_SETNAME
+struct MHD_named_helper_param_
+{
+ /**
+ * Real thread start routine
+ */
+ MHD_THREAD_START_ROUTINE_ start_routine;
+
+ /**
+ * Argument for thread start routine
+ */
+ void *arg;
+
+ /**
+ * Name for thread
+ */
+ const char *name;
+};
+
+
+static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
+named_thread_starter (void *data)
+{
+ struct MHD_named_helper_param_ *const param =
+ (struct MHD_named_helper_param_ *) data;
+ void *arg;
+ MHD_THREAD_START_ROUTINE_ thr_func;
+
+ if (NULL == data)
+ return (MHD_THRD_RTRN_TYPE_) 0;
+
+ MHD_set_cur_thread_name_ (param->name);
+
+ arg = param->arg;
+ thr_func = param->start_routine;
+ free (data);
+
+ return thr_func (arg);
+}
+
+
+#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
+
+
+/**
+ * Create a named thread and set the attributes according to our options.
+ *
+ * @param thread handle to initialize
+ * @param thread_name name for new thread
+ * @param stack_size size of stack for new thread, 0 for default
+ * @param start_routine main function of thread
+ * @param arg argument for start_routine
+ * @return non-zero on success; zero otherwise (with errno set)
+ */
+int
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+ const char*thread_name,
+ size_t stack_size,
+ MHD_THREAD_START_ROUTINE_ start_routine,
+ void *arg)
+{
+#if defined(MHD_USE_THREAD_ATTR_SETNAME)
+ int res;
+ pthread_attr_t attr;
+
+ res = pthread_attr_init (&attr);
+ if (0 == res)
+ {
+#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD)
+ /* NetBSD use 3 arguments: second argument is string in printf-like format,
+ * third argument is single argument for printf;
+ * OSF1 use 3 arguments too, but last one always must be zero (NULL).
+ * MHD doesn't use '%' in thread names, so both form are used in same way.
+ */res = pthread_attr_setname_np (&attr, thread_name, 0);
+#elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
+ res = pthread_attr_setname_np (&attr, thread_name);
+#else
+#error No pthread_attr_setname_np() function.
+#endif
+ if ((res == 0) && (0 != stack_size) )
+ res = pthread_attr_setstacksize (&attr,
+ stack_size);
+ if (0 == res)
+ res = pthread_create (&(thread->handle),
+ &attr,
+ start_routine,
+ arg);
+ pthread_attr_destroy (&attr);
+ }
+ if (0 != res)
+ errno = res;
+
+ return ! res;
+#else /* ! MHD_USE_THREAD_ATTR_SETNAME */
+ struct MHD_named_helper_param_ *param;
+
+ if (NULL == thread_name)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ param = malloc (sizeof (struct MHD_named_helper_param_));
+ if (NULL == param)
+ return 0;
+
+ param->start_routine = start_routine;
+ param->arg = arg;
+ param->name = thread_name;
+
+ /* Set thread name in thread itself to avoid problems with
+ * threads which terminated before name is set in other thread.
+ */
+ if (! MHD_create_thread_ (thread,
+ stack_size,
+ &named_thread_starter,
+ (void*) param))
+ {
+ free (param);
+ return 0;
+ }
+
+ return ! 0;
+#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
+}
+
+
+#endif /* MHD_USE_THREAD_NAME_ */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/mhd_threads.h
^
|
@@ -0,0 +1,237 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file microhttpd/mhd_threads.h
+ * @brief Header for platform-independent threads abstraction
+ * @author Karlson2k (Evgeny Grin)
+ *
+ * Provides basic abstraction for threads.
+ * Any functions can be implemented as macro on some platforms
+ * unless explicitly marked otherwise.
+ * Any function argument can be skipped in macro, so avoid
+ * variable modification in function parameters.
+ *
+ * @warning Unlike pthread functions, most of functions return
+ * nonzero on success.
+ */
+
+#ifndef MHD_THREADS_H
+#define MHD_THREADS_H 1
+
+#include "mhd_options.h"
+#ifdef HAVE_STDDEF_H
+# include <stddef.h> /* for size_t */
+#else /* ! HAVE_STDDEF_H */
+# include <stdlib.h> /* for size_t */
+#endif /* ! HAVE_STDDEF_H */
+
+#if defined(MHD_USE_POSIX_THREADS)
+# undef HAVE_CONFIG_H
+# include <pthread.h>
+# define HAVE_CONFIG_H 1
+#elif defined(MHD_USE_W32_THREADS)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif /* !WIN32_LEAN_AND_MEAN */
+# include <windows.h>
+#else
+# error No threading API is available.
+#endif
+
+#ifndef MHD_NO_THREAD_NAMES
+# if defined(MHD_USE_POSIX_THREADS)
+# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
+ defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
+ defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || \
+ defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
+# define MHD_USE_THREAD_NAME_
+# endif /* HAVE_PTHREAD_SETNAME_NP */
+# elif defined(MHD_USE_W32_THREADS)
+# ifdef _MSC_FULL_VER
+/* Thread names only available with VC compiler */
+# define MHD_USE_THREAD_NAME_
+# endif /* _MSC_FULL_VER */
+# endif
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+typedef pthread_t MHD_thread_handle_;
+#elif defined(MHD_USE_W32_THREADS)
+typedef HANDLE MHD_thread_handle_;
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+# define MHD_THRD_RTRN_TYPE_ void*
+# define MHD_THRD_CALL_SPEC_
+#elif defined(MHD_USE_W32_THREADS)
+# define MHD_THRD_RTRN_TYPE_ unsigned
+# define MHD_THRD_CALL_SPEC_ __stdcall
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+typedef pthread_t MHD_thread_ID_;
+#elif defined(MHD_USE_W32_THREADS)
+typedef DWORD MHD_thread_ID_;
+#endif
+
+/* Depending on implementation, pthread_create() MAY set thread ID into
+ * provided pointer and after it start thread OR start thread and after
+ * if set thread ID. In latter case, to avoid data races, additional
+ * pthread_self() call is required in thread routine. Is some platform
+ * is known for setting thread ID BEFORE starting thread macro
+ * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
+ * to save some resources. */
+#if defined(MHD_USE_POSIX_THREADS)
+# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+union _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+struct _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+#elif defined(MHD_USE_W32_THREADS)
+struct _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+/**
+ * Wait until specified thread is ended and free thread handle on success.
+ * @param thread handle to watch
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_join_thread_(thread) (! pthread_join ((thread), NULL))
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * Wait until specified thread is ended and free thread handle on success.
+ * @param thread handle to watch
+ * @return nonzero on success, zero otherwise
+ */
+#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject ( \
+ (thread), INFINITE) ? (CloseHandle ( \
+ (thread)), ! 0) : \
+ 0)
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+/**
+ * Check whether provided thread ID match current thread.
+ * @param ID thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_ID_match_current_(ID) (pthread_equal ((ID), pthread_self ()))
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * Check whether provided thread ID match current thread.
+ * @param ID thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId () == (ID))
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) (void) 0
+# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
+ pthread_self ())
+# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
+ GetCurrentThreadId ())
+#endif
+
+/**
+ * Signature of main function for a thread.
+ *
+ * @param cls closure argument for the function
+ * @return termination code from the thread
+ */
+typedef MHD_THRD_RTRN_TYPE_
+(MHD_THRD_CALL_SPEC_ *MHD_THREAD_START_ROUTINE_)(void *cls);
+
+
+/**
+ * Create a thread and set the attributes according to our options.
+ *
+ * If thread is created, thread handle must be freed by MHD_join_thread_().
+ *
+ * @param thread handle to initialize
+ * @param stack_size size of stack for new thread, 0 for default
+ * @param start_routine main function of thread
+ * @param arg argument for start_routine
+ * @return non-zero on success; zero otherwise
+ */
+int
+MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
+ size_t stack_size,
+ MHD_THREAD_START_ROUTINE_ start_routine,
+ void *arg);
+
+#ifndef MHD_USE_THREAD_NAME_
+#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_ ((t),(s),(r),(a))
+#else /* MHD_USE_THREAD_NAME_ */
+/**
+ * Create a named thread and set the attributes according to our options.
+ *
+ * @param thread handle to initialize
+ * @param thread_name name for new thread
+ * @param stack_size size of stack for new thread, 0 for default
+ * @param start_routine main function of thread
+ * @param arg argument for start_routine
+ * @return non-zero on success; zero otherwise
+ */
+int
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+ const char*thread_name,
+ size_t stack_size,
+ MHD_THREAD_START_ROUTINE_ start_routine,
+ void *arg);
+
+#endif /* MHD_USE_THREAD_NAME_ */
+
+#endif /* ! MHD_THREADS_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/panic.c
^
|
@@ -0,0 +1,61 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/panic.c
+ * @brief functions to panic (abort)
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Handler for fatal errors.
+ */
+MHD_PanicCallback mhd_panic = NULL;
+
+/**
+ * Closure argument for #mhd_panic.
+ */
+void *mhd_panic_cls = NULL;
+
+
+/**
+ * Sets the global error handler to a different implementation. @a cb
+ * will only be called in the case of typically fatal, serious
+ * internal consistency issues. These issues should only arise in the
+ * case of serious memory corruption or similar problems with the
+ * architecture. While @a cb is allowed to return and MHD will then
+ * try to continue, this is never safe.
+ *
+ * The default implementation that is used if no panic function is set
+ * simply prints an error message and calls `abort()`. Alternative
+ * implementations might call `exit()` or other similar functions.
+ *
+ * @param cb new error handler
+ * @param cls passed to @a cb
+ * @ingroup logging
+ */
+void
+MHD_set_panic_func (MHD_PanicCallback cb,
+ void *cls)
+{
+ mhd_panic = cb;
+ mhd_panic_cls = cls;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/reason_phrase.c
^
|
@@ -0,0 +1,182 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2011, 2017 Christian Grothoff, Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+/**
+ * @file reason_phrase.c
+ * @brief Tables of the string response phrases
+ * @author Elliot Glaysher
+ * @author Christian Grothoff (minor code clean up)
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "internal.h"
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+static const char *const invalid_hundred[] = {
+ NULL
+};
+
+static const char *const one_hundred[] = {
+ "Continue",
+ "Switching Protocols",
+ "Processing"
+};
+
+static const char *const two_hundred[] = {
+ "OK",
+ "Created",
+ "Accepted",
+ "Non-Authoritative Information",
+ "No Content",
+ "Reset Content",
+ "Partial Content",
+ "Multi-Status",
+ "Already Reported",
+ "Unknown",
+ "Unknown", /* 210 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 215 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 220 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 225 */
+ "IM Used"
+};
+
+static const char *const three_hundred[] = {
+ "Multiple Choices",
+ "Moved Permanently",
+ "Found",
+ "See Other",
+ "Not Modified",
+ "Use Proxy",
+ "Switch Proxy",
+ "Temporary Redirect",
+ "Permanent Redirect"
+};
+
+static const char *const four_hundred[] = {
+ "Bad Request",
+ "Unauthorized",
+ "Payment Required",
+ "Forbidden",
+ "Not Found",
+ "Method Not Allowed",
+ "Not Acceptable",
+ "Proxy Authentication Required",
+ "Request Timeout",
+ "Conflict",
+ "Gone",
+ "Length Required",
+ "Precondition Failed",
+ "Payload Too Large",
+ "URI Too Long",
+ "Unsupported Media Type",
+ "Range Not Satisfiable",
+ "Expectation Failed",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 420 */
+ "Misdirected Request",
+ "Unprocessable Entity",
+ "Locked",
+ "Failed Dependency",
+ "Unordered Collection",
+ "Upgrade Required",
+ "Unknown",
+ "Precondition Required",
+ "Too Many Requests",
+ "Unknown", /* 430 */
+ "Request Header Fields Too Large",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 435 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 440 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "No Response",
+ "Unknown", /* 445 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Retry With",
+ "Blocked by Windows Parental Controls", /* 450 */
+ "Unavailable For Legal Reasons"
+};
+
+static const char *const five_hundred[] = {
+ "Internal Server Error",
+ "Not Implemented",
+ "Bad Gateway",
+ "Service Unavailable",
+ "Gateway Timeout",
+ "HTTP Version Not Supported",
+ "Variant Also Negotiates",
+ "Insufficient Storage",
+ "Loop Detected",
+ "Bandwidth Limit Exceeded",
+ "Not Extended",
+ "Network Authentication Required"
+};
+
+
+struct MHD_Reason_Block
+{
+ size_t max;
+ const char *const*data;
+};
+
+#define BLOCK(m) { (sizeof(m) / sizeof(char*)), m }
+
+static const struct MHD_Reason_Block reasons[] = {
+ BLOCK (invalid_hundred),
+ BLOCK (one_hundred),
+ BLOCK (two_hundred),
+ BLOCK (three_hundred),
+ BLOCK (four_hundred),
+ BLOCK (five_hundred),
+};
+
+
+const char *
+MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code)
+{
+ if ( (code >= 100) &&
+ (code < 600) &&
+ (reasons[code / 100].max > (code % 100)) )
+ return reasons[code / 100].data[code % 100];
+ return "Unknown";
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/request.c
^
|
@@ -0,0 +1,160 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+/**
+ * @file requests.c
+ * @brief Methods for managing HTTP requests
+ * @author Daniel Pittman
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "internal.h"
+
+
+/**
+ * Get all of the headers from the request.
+ *
+ * @param request request to get values from
+ * @param kind types of values to iterate over, can be a bitmask
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup request
+ */
+unsigned int
+MHD_request_get_values (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ MHD_KeyValueIterator iterator,
+ void *iterator_cls)
+{
+ int ret;
+ struct MHD_HTTP_Header *pos;
+
+ ret = 0;
+ for (pos = request->headers_received;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if (0 != (pos->kind & kind))
+ {
+ ret++;
+ if ( (NULL != iterator) &&
+ (MHD_YES != iterator (iterator_cls,
+ pos->kind,
+ pos->header,
+ pos->value)) )
+ return ret;
+ }
+ }
+ return ret;
+}
+
+
+/**
+ * This function can be used to add an entry to the HTTP headers of a
+ * request (so that the #MHD_request_get_values function will
+ * return them -- and the `struct MHD_PostProcessor` will also see
+ * them). This maybe required in certain situations (see Mantis
+ * #1399) where (broken) HTTP implementations fail to supply values
+ * needed by the post processor (or other parts of the application).
+ *
+ * This function MUST only be called from within the
+ * request callbacks (otherwise, access maybe improperly
+ * synchronized). Furthermore, the client must guarantee that the key
+ * and value arguments are 0-terminated strings that are NOT freed
+ * until the connection is closed. (The easiest way to do this is by
+ * passing only arguments to permanently allocated strings.).
+ *
+ * @param request the request for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value
+ * @param value the value itself
+ * @return #MHD_NO if the operation could not be
+ * performed due to insufficient memory;
+ * #MHD_YES on success
+ * @ingroup request
+ */
+enum MHD_Bool
+MHD_request_set_value (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *value)
+{
+ struct MHD_HTTP_Header *pos;
+
+ pos = MHD_pool_allocate (request->connection->pool,
+ sizeof (struct MHD_HTTP_Header),
+ MHD_YES);
+ if (NULL == pos)
+ return MHD_NO;
+ pos->header = (char *) key;
+ pos->value = (char *) value;
+ pos->kind = kind;
+ pos->next = NULL;
+ /* append 'pos' to the linked list of headers */
+ if (NULL == request->headers_received_tail)
+ {
+ request->headers_received = pos;
+ request->headers_received_tail = pos;
+ }
+ else
+ {
+ request->headers_received_tail->next = pos;
+ request->headers_received_tail = pos;
+ }
+ return MHD_YES;
+}
+
+
+/**
+ * Get a particular header value. If multiple
+ * values match the kind, return any one of them.
+ *
+ * @param request request to get values from
+ * @param kind what kind of value are we looking for
+ * @param key the header to look for, NULL to lookup 'trailing' value without a key
+ * @return NULL if no such item was found
+ * @ingroup request
+ */
+const char *
+MHD_request_lookup_value (struct MHD_Request *request,
+ enum MHD_ValueKind kind,
+ const char *key)
+{
+ struct MHD_HTTP_Header *pos;
+
+ for (pos = request->headers_received;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if ((0 != (pos->kind & kind)) &&
+ ( (key == pos->header) ||
+ ( (NULL != pos->header) &&
+ (NULL != key) &&
+ (MHD_str_equal_caseless_ (key,
+ pos->header)))))
+ return pos->value;
+ }
+ return NULL;
+}
+
+
+/* end of request.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/request_info.c
^
|
@@ -0,0 +1,86 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/request_info.c
+ * @brief implementation of MHD_request_get_information_sz()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Obtain information about the given request.
+ * Use wrapper macro #MHD_request_get_information() instead of direct use
+ * of this function.
+ *
+ * @param request what request to get information about
+ * @param info_type what information is desired?
+ * @param[out] return_value pointer to union where requested information will
+ * be stored
+ * @param return_value_size size of union MHD_RequestInformation at compile
+ * time
+ * @return #MHD_YES on success, #MHD_NO on error
+ * (@a info_type is unknown, NULL pointer etc.)
+ * @ingroup specialized
+ */
+enum MHD_Bool
+MHD_request_get_information_sz (struct MHD_Request *request,
+ enum MHD_RequestInformationType info_type,
+ union MHD_RequestInformation *return_value,
+ size_t return_value_size)
+{
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
+ switch (info_type)
+ {
+ case MHD_REQUEST_INFORMATION_CONNECTION:
+ CHECK_SIZE (struct MHD_Connection *);
+ return_value->connection = request->connection;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_CLIENT_CONTEXT:
+ CHECK_SIZE (void **);
+ return_value->request_context = &request->client_context;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HTTP_VERSION:
+ CHECK_SIZE (const char *);
+ return_value->http_version = request->version_s;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HTTP_METHOD:
+ CHECK_SIZE (const char *);
+ return_value->http_method = request->method_s;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HEADER_SIZE:
+ CHECK_SIZE (size_t);
+ if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) ||
+ (MHD_REQUEST_CLOSED == request->state) )
+ return MHD_NO; /* invalid, too early! */
+ return_value->header_size = request->header_size;
+ return MHD_YES;
+
+ default:
+ return MHD_NO;
+ }
+
+#undef CHECK_SIZE
+}
+
+
+/* end of request_info.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/request_resume.c
^
|
@@ -0,0 +1,201 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/request_resume.c
+ * @brief implementation of MHD_request_resume()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "connection_close.h"
+
+/**
+ * Resume handling of network data for suspended request. It is
+ * safe to resume a suspended request at any time. Calling this
+ * function on a request that was not previously suspended will
+ * result in undefined behavior.
+ *
+ * If you are using this function in ``external'' select mode, you must
+ * make sure to run #MHD_run() afterwards (before again calling
+ * #MHD_get_fdset(), as otherwise the change may not be reflected in
+ * the set returned by #MHD_get_fdset() and you may end up with a
+ * request that is stuck until the next network activity.
+ *
+ * @param request the request to resume
+ */
+void
+MHD_request_resume (struct MHD_Request *request)
+{
+ struct MHD_Daemon *daemon = request->daemon;
+
+ if (daemon->disallow_suspend_resume)
+ MHD_PANIC (_ (
+ "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ request->connection->resuming = true;
+ daemon->resuming = true;
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc,
+ "r")) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_USE_FAILED,
+ _ (
+ "Failed to signal resume via inter-thread communication channel.\n"));
+#endif
+ }
+}
+
+
+/**
+ * Run through the suspended connections and move any that are no
+ * longer suspended back to the active state.
+ *
+ * @remark To be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon daemon context
+ * @return true if a connection was actually resumed
+ */
+bool
+MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
+/* FIXME: rename connections -> requests? */
+{
+ struct MHD_Connection *pos;
+ struct MHD_Connection *prev = NULL;
+ bool ret;
+ const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
+ daemon->threading_mode);
+
+ mhd_assert (NULL == daemon->worker_pool);
+ ret = false;
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+
+ if (daemon->resuming)
+ {
+ prev = daemon->suspended_connections_tail;
+ /* During shutdown check for resuming is forced. */
+ mhd_assert ((NULL != prev) || (daemon->shutdown));
+ }
+
+ daemon->resuming = false;
+
+ while (NULL != (pos = prev))
+ {
+#ifdef UPGRADE_SUPPORT
+ struct MHD_UpgradeResponseHandle *const urh = pos->request.urh;
+#else /* ! UPGRADE_SUPPORT */
+ static const void *const urh = NULL;
+#endif /* ! UPGRADE_SUPPORT */
+ prev = pos->prev;
+ if ( (! pos->resuming)
+#ifdef UPGRADE_SUPPORT
+ || ( (NULL != urh) &&
+ ( (! urh->was_closed) ||
+ (! urh->clean_ready) ) )
+#endif /* UPGRADE_SUPPORT */
+ )
+ continue;
+ ret = true;
+ mhd_assert (pos->suspended);
+ DLL_remove (daemon->suspended_connections_head,
+ daemon->suspended_connections_tail,
+ pos);
+ pos->suspended = false;
+ if (NULL == urh)
+ {
+ DLL_insert (daemon->connections_head,
+ daemon->connections_tail,
+ pos);
+ if (! used_thr_p_c)
+ {
+ /* Reset timeout timer on resume. */
+ if (0 != pos->connection_timeout)
+ pos->last_activity = MHD_monotonic_sec_counter ();
+
+ if (pos->connection_timeout == daemon->connection_default_timeout)
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ pos);
+ else
+ XDLL_insert (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ pos);
+ }
+#ifdef EPOLL_SUPPORT
+ if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
+ {
+ if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ MHD_PANIC ("Resumed connection was already in EREADY set.\n");
+ /* we always mark resumed connections as ready, as we
+ might have missed the edge poll event during suspension */
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
+ | MHD_EPOLL_STATE_READ_READY
+ | MHD_EPOLL_STATE_WRITE_READY;
+ pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
+ }
+#endif
+ }
+#ifdef UPGRADE_SUPPORT
+ else
+ {
+ struct MHD_Response *response = pos->request.response;
+
+ /* Data forwarding was finished (for TLS connections) AND
+ * application was closed upgraded connection.
+ * Insert connection into cleanup list. */
+ if ( (NULL != response) &&
+ (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
+ (NULL != response->termination_cb) )
+ response->termination_cb (response->termination_cb_cls,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK,
+ &pos->request.client_context);
+ DLL_insert (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ pos);
+
+ }
+#endif /* UPGRADE_SUPPORT */
+ pos->resuming = false;
+ }
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if ( (used_thr_p_c) &&
+ (ret) )
+ { /* Wake up suspended connections. */
+ if (! MHD_itc_activate_ (daemon->itc,
+ "w"))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_ITC_USE_FAILED,
+ _ (
+ "Failed to signal resume of connection via inter-thread communication channel.\n"));
+#endif
+ }
+ }
+ return ret;
+}
+
+
+/* end of request_resume.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/request_resume.h
^
|
@@ -0,0 +1,43 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/request_resume.h
+ * @brief implementation of MHD_request_resume()
+ * @author Christian Grothoff
+ */
+
+
+#ifndef REQUEST_RESUME_H
+#define REQUEST_RESUME_H
+
+/**
+ * Run through the suspended connections and move any that are no
+ * longer suspended back to the active state.
+ * @remark To be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon daemon context
+ * @return true if a connection was actually resumed
+ */
+bool
+MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
+MHD_NONNULL (1);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response.c
^
|
@@ -0,0 +1,260 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response.c
+ * @brief implementation of general response functions
+ * @author Daniel Pittman
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "internal.h"
+
+
+/**
+ * Add a header or footer line to the response.
+ *
+ * @param response response to add a header to
+ * @param kind header or footer
+ * @param header the header to add
+ * @param content value to add
+ * @return false on error (i.e. invalid header or content format).
+ */
+static bool
+add_response_entry (struct MHD_Response *response,
+ enum MHD_ValueKind kind,
+ const char *header,
+ const char *content)
+{
+ struct MHD_HTTP_Header *hdr;
+
+ if ( (NULL == header) ||
+ (NULL == content) ||
+ (0 == header[0]) ||
+ (0 == content[0]) ||
+ (NULL != strchr (header, '\t')) ||
+ (NULL != strchr (header, '\r')) ||
+ (NULL != strchr (header, '\n')) ||
+ (NULL != strchr (content, '\t')) ||
+ (NULL != strchr (content, '\r')) ||
+ (NULL != strchr (content, '\n')) )
+ return false;
+ if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
+ return false;
+ if (NULL == (hdr->header = strdup (header)))
+ {
+ free (hdr);
+ return false;
+ }
+ if (NULL == (hdr->value = strdup (content)))
+ {
+ free (hdr->header);
+ free (hdr);
+ return false;
+ }
+ hdr->kind = kind;
+ hdr->next = response->first_header;
+ response->first_header = hdr;
+ return true;
+}
+
+
+/**
+ * Explicitly decrease reference counter of a response object. If the
+ * counter hits zero, destroys a response object and associated
+ * resources. Usually, this is implicitly done by converting a
+ * response to an action and returning the action to MHD.
+ *
+ * @param response response to decrement RC of
+ * @ingroup response
+ */
+void
+MHD_response_queue_for_destroy (struct MHD_Response *response)
+{
+ struct MHD_HTTP_Header *pos;
+
+ MHD_mutex_lock_chk_ (&response->mutex);
+ if (0 != --(response->reference_count))
+ {
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ return;
+ }
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ MHD_mutex_destroy_chk_ (&response->mutex);
+ if (NULL != response->crfc)
+ response->crfc (response->crc_cls);
+ while (NULL != response->first_header)
+ {
+ pos = response->first_header;
+ response->first_header = pos->next;
+ free (pos->header);
+ free (pos->value);
+ free (pos);
+ }
+ free (response);
+}
+
+
+/**
+ * Add a header line to the response.
+ *
+ * @param response response to add a header to
+ * @param header the header to add
+ * @param content value to add
+ * @return #MHD_NO on error (i.e. invalid header or content format),
+ * or out of memory
+ * @ingroup response
+ */
+enum MHD_Bool
+MHD_response_add_header (struct MHD_Response *response,
+ const char *header,
+ const char *content)
+{
+ return add_response_entry (response,
+ MHD_HEADER_KIND,
+ header,
+ content) ? MHD_YES : MHD_NO;
+}
+
+
+/**
+ * Add a tailer line to the response.
+ *
+ * @param response response to add a footer to
+ * @param footer the footer to add
+ * @param content value to add
+ * @return #MHD_NO on error (i.e. invalid footer or content format),
+ * or out of memory
+ * @ingroup response
+ */
+enum MHD_Bool
+MHD_response_add_trailer (struct MHD_Response *response,
+ const char *footer,
+ const char *content)
+{
+ return add_response_entry (response,
+ MHD_FOOTER_KIND,
+ footer,
+ content) ? MHD_YES : MHD_NO;
+}
+
+
+/**
+ * Delete a header (or footer) line from the response.
+ *
+ * @param response response to remove a header from
+ * @param header the header to delete
+ * @param content value to delete
+ * @return #MHD_NO on error (no such header known)
+ * @ingroup response
+ */
+enum MHD_Bool
+MHD_response_del_header (struct MHD_Response *response,
+ const char *header,
+ const char *content)
+{
+ struct MHD_HTTP_Header *pos;
+ struct MHD_HTTP_Header *prev;
+
+ prev = NULL;
+ pos = response->first_header;
+ while (NULL != pos)
+ {
+ if ((0 == strcmp (header,
+ pos->header)) &&
+ (0 == strcmp (content,
+ pos->value)))
+ {
+ free (pos->header);
+ free (pos->value);
+ if (NULL == prev)
+ response->first_header = pos->next;
+ else
+ prev->next = pos->next;
+ free (pos);
+ return MHD_YES;
+ }
+ prev = pos;
+ pos = pos->next;
+ }
+ return MHD_NO;
+}
+
+
+/**
+ * Get all of the headers (and footers) added to a response.
+ *
+ * @param response response to query
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over
+ * @ingroup response
+ */
+unsigned int
+MHD_response_get_headers (struct MHD_Response *response,
+ MHD_KeyValueIterator iterator,
+ void *iterator_cls)
+{
+ unsigned int numHeaders = 0;
+ struct MHD_HTTP_Header *pos;
+
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ numHeaders++;
+ if ( (NULL != iterator) &&
+ (MHD_YES != iterator (iterator_cls,
+ pos->kind,
+ pos->header,
+ pos->value)) )
+ break;
+ }
+ return numHeaders;
+}
+
+
+/**
+ * Get a particular header (or footer) from the response.
+ *
+ * @param response response to query
+ * @param key which header to get
+ * @return NULL if header does not exist
+ * @ingroup response
+ */
+const char *
+MHD_response_get_header (struct MHD_Response *response,
+ const char *key)
+{
+ struct MHD_HTTP_Header *pos;
+
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if (MHD_str_equal_caseless_ (pos->header,
+ key))
+ return pos->value;
+ }
+ return NULL;
+}
+
+
+/* end of response.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response_for_upgrade.c
^
|
@@ -0,0 +1,95 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response_for_upgrade.c
+ * @brief implementation of MHD_response_for_upgrade()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Create a response object that can be used for 101 UPGRADE
+ * responses, for example to implement WebSockets. After sending the
+ * response, control over the data stream is given to the callback (which
+ * can then, for example, start some bi-directional communication).
+ * If the response is queued for multiple connections, the callback
+ * will be called for each connection. The callback
+ * will ONLY be called after the response header was successfully passed
+ * to the OS; if there are communication errors before, the usual MHD
+ * connection error handling code will be performed.
+ *
+ * MHD will automatically set the correct HTTP status
+ * code (#MHD_HTTP_SWITCHING_PROTOCOLS).
+ * Setting correct HTTP headers for the upgrade must be done
+ * manually (this way, it is possible to implement most existing
+ * WebSocket versions using this API; in fact, this API might be useful
+ * for any protocol switch, not just WebSockets). Note that
+ * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
+ * way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
+ * cannot be generated; instead, MHD will always produce "HTTP/1.1 101
+ * Switching Protocols" (if the response code 101 is used).
+ *
+ * As usual, the response object can be extended with header
+ * information and then be used any number of times (as long as the
+ * header information is not connection-specific).
+ *
+ * @param upgrade_handler function to call with the "upgraded" socket
+ * @param upgrade_handler_cls closure for @a upgrade_handler
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+struct MHD_Response *
+MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
+ void *upgrade_handler_cls)
+{
+#ifdef UPGRADE_SUPPORT
+ struct MHD_Response *response;
+
+ mhd_assert (NULL != upgrade_handler);
+ response = MHD_calloc_ (1,
+ sizeof (struct MHD_Response));
+ if (NULL == response)
+ return NULL;
+ if (! MHD_mutex_init_ (&response->mutex))
+ {
+ free (response);
+ return NULL;
+ }
+ response->upgrade_handler = upgrade_handler;
+ response->upgrade_handler_cls = upgrade_handler_cls;
+ response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS;
+ response->total_size = MHD_SIZE_UNKNOWN;
+ response->reference_count = 1;
+ if (MHD_NO ==
+ MHD_response_add_header (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "Upgrade"))
+ {
+ MHD_response_queue_for_destroy (response);
+ return NULL;
+ }
+ return response;
+#else
+ return NULL;
+#endif
+}
+
+
+/* end of response_for_upgrade.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response_from_buffer.c
^
|
@@ -0,0 +1,89 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response_from_buffer.c
+ * @brief implementation of MHD_response_from_buffer()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to use for the response;
+ * #MHD_HTTP_NO_CONTENT is only valid if @a size is 0;
+ * @param size size of the data portion of the response
+ * @param buffer size bytes containing the response's data portion
+ * @param mode flags for buffer management
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+struct MHD_Response *
+MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
+ size_t size,
+ void *buffer,
+ enum MHD_ResponseMemoryMode mode)
+{
+ struct MHD_Response *response;
+ void *tmp;
+
+ mhd_assert ( (NULL != buffer) ||
+ (0 == size) );
+ if (NULL ==
+ (response = MHD_calloc_ (1,
+ sizeof (struct MHD_Response))))
+ return NULL;
+ response->fd = -1;
+ if (! MHD_mutex_init_ (&response->mutex))
+ {
+ free (response);
+ return NULL;
+ }
+ if ( (MHD_RESPMEM_MUST_COPY == mode) &&
+ (size > 0) )
+ {
+ if (NULL == (tmp = malloc (size)))
+ {
+ MHD_mutex_destroy_chk_ (&response->mutex);
+ free (response);
+ return NULL;
+ }
+ memcpy (tmp,
+ buffer,
+ size);
+ buffer = tmp;
+ }
+ if (MHD_RESPMEM_PERSISTENT != mode)
+ {
+ response->crfc = &free;
+ response->crc_cls = buffer;
+ }
+ response->status_code = sc;
+ response->reference_count = 1;
+ response->total_size = size;
+ response->data = buffer;
+ response->data_size = size;
+ return response;
+}
+
+
+/* end of response_from_buffer.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response_from_callback.c
^
|
@@ -0,0 +1,80 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response_from_callback.c
+ * @brief implementation of MHD_response_from_callback()
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Create a response action. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to return
+ * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
+ * @param block_size preferred block size for querying crc (advisory only,
+ * MHD may still call @a crc using smaller chunks); this
+ * is essentially the buffer size used for IO, clients
+ * should pick a value that is appropriate for IO and
+ * memory performance requirements
+ * @param crc callback to use to obtain response data
+ * @param crc_cls extra argument to @a crc
+ * @param crfc callback to call to free @a crc_cls resources
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+struct MHD_Response *
+MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
+ uint64_t size,
+ size_t block_size,
+ MHD_ContentReaderCallback crc,
+ void *crc_cls,
+ MHD_ContentReaderFreeCallback crfc)
+{
+ struct MHD_Response *response;
+
+ mhd_assert (NULL != crc);
+ mhd_assert (0 != block_size);
+ if (NULL ==
+ (response = MHD_calloc_ (1,
+ sizeof (struct MHD_Response)
+ + block_size)))
+ return NULL;
+ response->fd = -1;
+ response->status_code = sc;
+ response->data = (void *) &response[1];
+ response->data_buffer_size = block_size;
+ if (! MHD_mutex_init_ (&response->mutex))
+ {
+ free (response);
+ return NULL;
+ }
+ response->crc = crc;
+ response->crfc = crfc;
+ response->crc_cls = crc_cls;
+ response->reference_count = 1;
+ response->total_size = size;
+ return response;
+}
+
+
+/* end of response_from_callback.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response_from_fd.c
^
|
@@ -0,0 +1,211 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2019 Daniel Pittman, Christian Grothoff and
+ Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response_from_fd.c
+ * @brief implementation of MHD_response_from_fd()
+ * @author Daniel Pittman
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "internal.h"
+
+
+/**
+ * Size of single file read operation for
+ * file-backed responses.
+ */
+#ifndef MHD_FILE_READ_BLOCK_SIZE
+#ifdef _WIN32
+#define MHD_FILE_READ_BLOCK_SIZE 16384 /* 16k */
+#else /* _WIN32 */
+#define MHD_FILE_READ_BLOCK_SIZE 4096 /* 4k */
+#endif /* _WIN32 */
+#endif /* !MHD_FD_BLOCK_SIZE */
+
+/**
+ * Given a file descriptor, read data from the file
+ * to generate the response.
+ *
+ * @param cls pointer to the response
+ * @param pos offset in the file to access
+ * @param buf where to write the data
+ * @param max number of bytes to write at most
+ * @return number of bytes written
+ */
+static ssize_t
+file_reader (void *cls,
+ uint64_t pos,
+ char *buf,
+ size_t max)
+{
+ struct MHD_Response *response = cls;
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+ ssize_t n;
+#else /* _WIN32 && !__CYGWIN__ */
+ const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
+#endif /* _WIN32 && !__CYGWIN__ */
+ const int64_t offset64 = (int64_t) (pos + response->fd_off);
+
+ if (offset64 < 0)
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
+
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+ if (max > SSIZE_MAX)
+ max = SSIZE_MAX; /* Clamp to maximum return value. */
+
+#if defined(HAVE_PREAD64)
+ n = pread64 (response->fd,
+ buf,
+ max,
+ offset64);
+#elif defined(HAVE_PREAD)
+ if ( (sizeof(off_t) < sizeof (uint64_t)) &&
+ (offset64 > (uint64_t) INT32_MAX) )
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
+
+ n = pread (response->fd,
+ buf,
+ max,
+ (off_t) offset64);
+#else /* ! HAVE_PREAD */
+#if defined(HAVE_LSEEK64)
+ if (lseek64 (response->fd,
+ offset64,
+ SEEK_SET) != offset64)
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
+#else /* ! HAVE_LSEEK64 */
+ if ( (sizeof(off_t) < sizeof (uint64_t)) &&
+ (offset64 > (uint64_t) INT32_MAX) )
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
+
+ if (lseek (response->fd,
+ (off_t) offset64,
+ SEEK_SET) != (off_t) offset64)
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
+#endif /* ! HAVE_LSEEK64 */
+ n = read (response->fd,
+ buf,
+ max);
+
+#endif /* ! HAVE_PREAD */
+ if (0 == n)
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ if (n < 0)
+ return MHD_CONTENT_READER_END_WITH_ERROR;
+ return n;
+#else /* _WIN32 && !__CYGWIN__ */
+ if (INVALID_HANDLE_VALUE == fh)
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
+ else
+ {
+ OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
+ ULARGE_INTEGER pos_uli;
+ DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
+ DWORD resRead;
+
+ pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
+ f_ol.Offset = pos_uli.LowPart;
+ f_ol.OffsetHigh = pos_uli.HighPart;
+ if (! ReadFile (fh,
+ (void*) buf,
+ toRead,
+ &resRead,
+ &f_ol))
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
+ if (0 == resRead)
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ return (ssize_t) resRead;
+ }
+#endif /* _WIN32 && !__CYGWIN__ */
+}
+
+
+/**
+ * Destroy file reader context. Closes the file
+ * descriptor.
+ *
+ * @param cls pointer to file descriptor
+ */
+static void
+free_callback (void *cls)
+{
+ struct MHD_Response *response = cls;
+
+ (void) close (response->fd);
+ response->fd = -1;
+}
+
+
+/**
+ * Create a response object based on an @a fd from which
+ * data is read. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param sc status code to return
+ * @param fd file descriptor referring to a file on disk with the
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @param offset offset to start reading from in the file;
+ * reading file beyond 2 GiB may be not supported by OS or
+ * MHD build; see ::MHD_FEATURE_LARGE_FILE
+ * @param size size of the data portion of the response;
+ * sizes larger than 2 GiB may be not supported by OS or
+ * MHD build; see ::MHD_FEATURE_LARGE_FILE
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+struct MHD_Response *
+MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
+ int fd,
+ uint64_t offset,
+ uint64_t size)
+{
+ struct MHD_Response *response;
+
+ mhd_assert (-1 != fd);
+#if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
+ if ( (sizeof (uint64_t) > sizeof (off_t)) &&
+ ( (size > (uint64_t) INT32_MAX) ||
+ (offset > (uint64_t) INT32_MAX) ||
+ ((size + offset) >= (uint64_t) INT32_MAX) ) )
+ return NULL;
+#endif
+ if ( ((int64_t) size < 0) ||
+ ((int64_t) offset < 0) ||
+ ((int64_t) (size + offset) < 0) )
+ return NULL;
+
+ response = MHD_response_from_callback (sc,
+ size,
+ MHD_FILE_READ_BLOCK_SIZE,
+ &file_reader,
+ NULL,
+ &free_callback);
+ if (NULL == response)
+ return NULL;
+ response->fd = fd;
+ response->fd_off = offset;
+ response->crc_cls = response;
+ return response;
+}
+
+
+/* end of response_from_fd.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/response_options.c
^
|
@@ -0,0 +1,62 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/response_option.c
+ * @brief implementation of response options
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Only respond in conservative HTTP 1.0-mode. In
+ * particular, do not (automatically) sent "Connection" headers and
+ * always close the connection after generating the response.
+ *
+ * @param request the request for which we force HTTP 1.0 to be used
+ */
+void
+MHD_response_option_v10_only (struct MHD_Response *response)
+{
+ response->v10_only = true;
+}
+
+
+/**
+ * Set a function to be called once MHD is finished with the
+ * request.
+ *
+ * @param response which response to set the callback for
+ * @param termination_cb function to call
+ * @param termination_cb_cls closure for @e termination_cb
+ */
+void
+MHD_response_option_termination_callback (struct MHD_Response *response,
+ MHD_RequestTerminationCallback
+ termination_cb,
+ void *termination_cb_cls)
+{
+ /* Q: should we assert termination_cb non-NULL? */
+ response->termination_cb = termination_cb;
+ response->termination_cb_cls = termination_cb_cls;
+}
+
+
+/* end of response_option.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/sysfdsetsize.c
^
|
@@ -0,0 +1,80 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/sysfdsetsize.c
+ * @brief Helper for obtaining FD_SETSIZE system default value
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+
+#include "MHD_config.h"
+
+#ifdef FD_SETSIZE
+/* FD_SETSIZE was defined before system headers. */
+/* To get system value of FD_SETSIZE, undefine FD_SETSIZE
+ here. */
+#undef FD_SETSIZE
+#endif /* FD_SETSIZE */
+
+#include <stdlib.h>
+#if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS)
+#include <sockLib.h>
+#endif /* OS_VXWORKS */
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+#if HAVE_TIME_H
+#include <time.h>
+#endif /* HAVE_TIME_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
+
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <winsock2.h>
+#endif /* _WIN32 && !__CYGWIN__ */
+
+#ifndef FD_SETSIZE
+#error FD_SETSIZE must be defined in system headers
+#endif /* !FD_SETSIZE */
+
+#include "sysfdsetsize.h"
+
+/**
+ * Get system default value of FD_SETSIZE
+ * @return system default value of FD_SETSIZE
+ */
+int
+get_system_fdsetsize_value (void)
+{
+ return FD_SETSIZE;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/sysfdsetsize.h
^
|
@@ -0,0 +1,36 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2015 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/sysfdsetsize.h
+ * @brief Helper for obtaining FD_SETSIZE system default value
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef SYSFDSETSIZE_H
+#define SYSFDSETSIZE_H 1
+
+/**
+ * Get system default value of FD_SETSIZE
+ * @return system default value of FD_SETSIZE
+ */
+int
+get_system_fdsetsize_value (void);
+
+#endif /* !SYSFDSETSIZE_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/tsearch.c
^
|
@@ -0,0 +1,144 @@
+/*
+ * Tree search generalized from Knuth (6.2.2) Algorithm T just like
+ * the AT&T man page says.
+ *
+ * The node_t structure is for internal use only, lint doesn't grok it.
+ *
+ * Written by reading the System V Interface Definition, not the code.
+ *
+ * Totally public domain.
+ */
+
+#include "tsearch.h"
+#include <stdlib.h>
+
+
+typedef struct node
+{
+ const void *key;
+ struct node *llink;
+ struct node *rlink;
+} node_t;
+
+
+/* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */
+/* find or insert datum into search tree */
+void *
+tsearch (const void *vkey, /* key to be located */
+ void **vrootp, /* address of tree root */
+ int (*compar)(const void *, const void *))
+{
+ node_t *q;
+ node_t **rootp = (node_t **) vrootp;
+
+ if (NULL == rootp)
+ return NULL;
+
+ while (*rootp != NULL)
+ { /* Knuth's T1: */
+ int r;
+
+ if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
+ return *rootp; /* we found it! */
+
+ rootp = (r < 0) ?
+ &(*rootp)->llink : /* T3: follow left branch */
+ &(*rootp)->rlink; /* T4: follow right branch */
+ }
+
+ q = malloc (sizeof(node_t)); /* T5: key not found */
+ if (q)
+ { /* make new node */
+ *rootp = q; /* link new node to old */
+ q->key = vkey; /* initialize new node */
+ q->llink = q->rlink = NULL;
+ }
+ return q;
+}
+
+
+/* $NetBSD: tfind.c,v 1.5 2005/03/23 08:16:53 kleink Exp $ */
+/* find a node, or return NULL */
+void *
+tfind (const void *vkey, /* key to be found */
+ void *const *vrootp, /* address of the tree root */
+ int (*compar)(const void *, const void *))
+{
+ node_t *const *rootp = (node_t *const*) vrootp;
+
+ if (NULL == rootp)
+ return NULL;
+
+ while (*rootp != NULL)
+ { /* T1: */
+ int r;
+
+ if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
+ return *rootp; /* key found */
+ rootp = (r < 0) ?
+ &(*rootp)->llink : /* T3: follow left branch */
+ &(*rootp)->rlink; /* T4: follow right branch */
+ }
+ return NULL;
+}
+
+
+/* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */
+/*
+ * delete node with given key
+ *
+ * vkey: key to be deleted
+ * vrootp: address of the root of the tree
+ * compar: function to carry out node comparisons
+ */
+void *
+tdelete (const void *__restrict vkey,
+ void **__restrict vrootp,
+ int (*compar)(const void *, const void *))
+{
+ node_t **rootp = (node_t **) vrootp;
+ node_t *p;
+ node_t *q;
+ node_t *r;
+ int cmp;
+
+ if ((rootp == NULL) || ((p = *rootp) == NULL))
+ return NULL;
+
+ while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0)
+ {
+ p = *rootp;
+ rootp = (cmp < 0) ?
+ &(*rootp)->llink : /* follow llink branch */
+ &(*rootp)->rlink; /* follow rlink branch */
+ if (*rootp == NULL)
+ return NULL; /* key not found */
+ }
+ r = (*rootp)->rlink; /* D1: */
+ if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
+ {
+ q = r;
+ }
+ else if (r != NULL)
+ { /* Right link is NULL? */
+ if (r->llink == NULL)
+ { /* D2: Find successor */
+ r->llink = q;
+ q = r;
+ }
+ else
+ { /* D3: Find NULL link */
+ for (q = r->llink; q->llink != NULL; q = r->llink)
+ r = q;
+ r->llink = q->rlink;
+ q->llink = (*rootp)->llink;
+ q->rlink = (*rootp)->rlink;
+ }
+ }
+ free (*rootp); /* D4: Free node */
+ *rootp = q; /* link parent to new node */
+ return p;
+}
+
+
+/* end of tsearch.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/tsearch.h
^
|
@@ -0,0 +1,38 @@
+/*-
+ * Written by J.T. Conklin <jtc@netbsd.org>
+ * Public domain.
+ *
+ * $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
+ * $FreeBSD: release/9.0.0/include/search.h 105250 2002-10-16 14:29:23Z robert $
+ */
+
+#ifndef _TSEARCH_H_
+#define _TSEARCH_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+
+void *
+ tdelete (const void *__restrict,
+ void **__restrict,
+ int (*)(const void *, const void *));
+
+
+void *
+ tfind (const void *,
+ void *const *,
+ int (*)(const void *, const void *));
+
+
+void *
+ tsearch (const void *,
+ void **,
+ int (*)(const void *, const void *));
+
+#if defined(__cplusplus)
+};
+#endif /* __cplusplus */
+
+#endif /* !_TSEARCH_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/upgrade_process.c
^
|
@@ -0,0 +1,395 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/upgrade_process.c
+ * @brief function to process upgrade activity (over TLS)
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+#include "upgrade_process.h"
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Performs bi-directional forwarding on upgraded HTTPS connections
+ * based on the readiness state stored in the @a urh handle.
+ * @remark To be called only from thread that process
+ * connection's recv(), send() and response.
+ *
+ * @param urh handle to process
+ */
+void
+MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
+{
+ /* Help compiler to optimize:
+ * pointers to 'connection' and 'daemon' are not changed
+ * during this processing, so no need to chain dereference
+ * each time. */
+ struct MHD_Connection *const connection = urh->connection;
+ struct MHD_Daemon *const daemon = connection->daemon;
+ /* Prevent data races: use same value of 'was_closed' throughout
+ * this function. If 'was_closed' changed externally in the middle
+ * of processing - it will be processed on next iteration. */
+ bool was_closed;
+ struct MHD_TLS_Plugin *tls = daemon->tls_api;
+
+ if (daemon->shutdown)
+ {
+ /* Daemon shutting down, application will not receive any more data. */
+#ifdef HAVE_MESSAGES
+ if (! urh->was_closed)
+ {
+ MHD_DLOG (daemon,
+ MHD_SC_DAEMON_ALREADY_SHUTDOWN,
+ _ (
+ "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
+ }
+#endif
+ urh->was_closed = true;
+ }
+ was_closed = urh->was_closed;
+ if (was_closed)
+ {
+ /* Application was closed connections: no more data
+ * can be forwarded to application socket. */
+ if (0 < urh->in_buffer_used)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
+ _ (
+ "Failed to forward to application "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from remote side: application shut down socket.\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
+#endif
+
+ }
+ /* If application signaled MHD about socket closure then
+ * check for any pending data even if socket is not marked
+ * as 'ready' (signal may arrive after poll()/select()).
+ * Socketpair for forwarding is always in non-blocking mode
+ * so no risk that recv() will block the thread. */if (0 != urh->out_buffer_size)
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ /* Discard any data received form remote. */
+ urh->in_buffer_used = 0;
+ /* Do not try to push data to application. */
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Reading from remote client is not required anymore. */
+ urh->in_buffer_size = 0;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ connection->tls_read_ready = false;
+ }
+
+ /* On some platforms (W32, possibly Darwin) failed send() (send() will always
+ * fail after remote disconnect was detected) may discard data in system
+ * buffers received by system but not yet read by recv().
+ * So, before trying send() on any socket, recv() must be performed at first
+ * otherwise last part of incoming data may be lost. *//* If disconnect or error was detected - try to read from socket
+ * to dry data possibly pending is system buffers. */if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+
+ /*
+ * handle reading from remote TLS client
+ */
+ if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
+ (connection->tls_read_ready) ) &&
+ (urh->in_buffer_used < urh->in_buffer_size) )
+ {
+ ssize_t res;
+ size_t buf_size;
+
+ buf_size = urh->in_buffer_size - urh->in_buffer_used;
+ if (buf_size > SSIZE_MAX)
+ buf_size = SSIZE_MAX;
+
+ connection->tls_read_ready = false;
+ res = tls->recv (tls->cls,
+ connection->tls_cs,
+ &urh->in_buffer[urh->in_buffer_used],
+ buf_size);
+ if (0 >= res)
+ {
+ // FIXME: define GNUTLS-independent error codes!
+ if (GNUTLS_E_INTERRUPTED != res)
+ {
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ if (GNUTLS_E_AGAIN != res)
+ {
+ /* Unrecoverable error on socket was detected or
+ * socket was disconnected/shut down. */
+ /* Stop trying to read from this TLS socket. */
+ urh->in_buffer_size = 0;
+ }
+ }
+ }
+ else /* 0 < res */
+ {
+ urh->in_buffer_used += res;
+ if (buf_size > (size_t) res)
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ else if (0 < tls->check_record_pending (tls->cls,
+ connection->tls_cs))
+ connection->tls_read_ready = true;
+ }
+ if (MHD_EPOLL_STATE_ERROR ==
+ ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was read from system buffers. */
+ /* Stop trying to read from this TLS socket. */
+ urh->in_buffer_size = 0;
+ }
+ }
+
+ /*
+ * handle reading from application
+ */
+ if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
+ (urh->out_buffer_used < urh->out_buffer_size) )
+ {
+ ssize_t res;
+ size_t buf_size;
+
+ buf_size = urh->out_buffer_size - urh->out_buffer_used;
+ if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
+ buf_size = MHD_SCKT_SEND_MAX_SIZE_;
+
+ res = MHD_recv_ (urh->mhd.socket,
+ &urh->out_buffer[urh->out_buffer_used],
+ buf_size);
+ if (0 >= res)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if ((0 == res) ||
+ ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
+ (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
+ {
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ if ((0 == res) ||
+ (was_closed) ||
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
+ (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
+ {
+ /* Socket disconnect/shutdown was detected;
+ * Application signaled about closure of 'upgraded' socket;
+ * or persistent / unrecoverable error. */
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ }
+ }
+ }
+ else /* 0 < res */
+ {
+ urh->out_buffer_used += res;
+ if (buf_size > (size_t) res)
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+ if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
+ ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
+ (was_closed) ) )
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was read from system buffers. */
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ }
+ }
+
+ /*
+ * handle writing to remote HTTPS client
+ */
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
+ (urh->out_buffer_used > 0) )
+ {
+ ssize_t res;
+ size_t data_size;
+
+ data_size = urh->out_buffer_used;
+ if (data_size > SSIZE_MAX)
+ data_size = SSIZE_MAX;
+
+ res = tls->send (tls->cls,
+ connection->tls_cs,
+ urh->out_buffer,
+ data_size);
+ if (0 >= res)
+ {
+ // FIXME: define GNUTLS-independent error codes!
+ if (GNUTLS_E_INTERRUPTED != res)
+ {
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ if (GNUTLS_E_INTERRUPTED != res)
+ {
+ /* TLS connection shut down or
+ * persistent / unrecoverable error. */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
+ _ (
+ "Failed to forward to remote client "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from application: %s\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
+ tls->strerror (tls->cls,
+ res));
+#endif
+ /* Discard any data unsent to remote. */
+ urh->out_buffer_used = 0;
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+ }
+ }
+ else /* 0 < res */
+ {
+ const size_t next_out_buffer_used = urh->out_buffer_used - res;
+ if (0 != next_out_buffer_used)
+ {
+ memmove (urh->out_buffer,
+ &urh->out_buffer[res],
+ next_out_buffer_used);
+ if (data_size > (size_t) res)
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ }
+ urh->out_buffer_used = next_out_buffer_used;
+ }
+ if ( (0 == urh->out_buffer_used) &&
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was sent to remote. */
+ /* Do not try to send to remote anymore. */
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+ }
+
+ /*
+ * handle writing to application
+ */
+ if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
+ (urh->in_buffer_used > 0) )
+ {
+ ssize_t res;
+ size_t data_size;
+
+ data_size = urh->in_buffer_used;
+ if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
+ data_size = MHD_SCKT_SEND_MAX_SIZE_;
+
+ res = MHD_send_ (urh->mhd.socket,
+ urh->in_buffer,
+ data_size);
+ if (0 >= res)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
+ (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
+ {
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+ /* Socketpair connection shut down or
+ * persistent / unrecoverable error. */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
+ _ (
+ "Failed to forward to application "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from remote side: %s\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
+ MHD_socket_strerr_ (err));
+#endif
+ /* Discard any data received form remote. */
+ urh->in_buffer_used = 0;
+ /* Reading from remote client is not required anymore. */
+ urh->in_buffer_size = 0;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ connection->tls_read_ready = false;
+ }
+ }
+ }
+ else /* 0 < res */
+ {
+ const size_t next_in_buffer_used = urh->in_buffer_used - res;
+ if (0 != next_in_buffer_used)
+ {
+ memmove (urh->in_buffer,
+ &urh->in_buffer[res],
+ next_in_buffer_used);
+ if (data_size > (size_t) res)
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ }
+ urh->in_buffer_used = next_in_buffer_used;
+ }
+ if ( (0 == urh->in_buffer_used) &&
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
+ {
+ /* Do not try to push data to application. */
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Reading from remote client is not required anymore. */
+ urh->in_buffer_size = 0;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ connection->tls_read_ready = false;
+ }
+ }
+
+ /* Check whether data is present in TLS buffers
+ * and incoming forward buffer have some space. */
+ if ( (connection->tls_read_ready) &&
+ (urh->in_buffer_used < urh->in_buffer_size) &&
+ (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
+ daemon->data_already_pending = true;
+
+ if ( (daemon->shutdown) &&
+ ( (0 != urh->out_buffer_size) ||
+ (0 != urh->out_buffer_used) ) )
+ {
+ /* Daemon shutting down, discard any remaining forward data. */
+#ifdef HAVE_MESSAGES
+ if (0 < urh->out_buffer_used)
+ MHD_DLOG (daemon,
+ MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
+ _ (
+ "Failed to forward to remote client "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from application: daemon shut down.\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
+#endif
+ /* Discard any data unsent to remote. */
+ urh->out_buffer_used = 0;
+ /* Do not try to sent to remote anymore. */
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+}
+
+
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+/* end of upgrade_process.c */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/upgrade_process.h
^
|
@@ -0,0 +1,44 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+/**
+ * @file lib/upgrade_process.h
+ * @brief function to process upgrade activity (over TLS)
+ * @author Christian Grothoff
+ */
+#ifndef UPGRADE_PROCESS_H
+#define UPGRADE_PROCESS_H
+
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+/**
+ * Performs bi-directional forwarding on upgraded HTTPS connections
+ * based on the readiness state stored in the @a urh handle.
+ * @remark To be called only from thread that process
+ * connection's recv(), send() and response.
+ *
+ * @param urh handle to process
+ */
+void
+MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
+MHD_NONNULL (1);
+
+
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/lib/version.c
^
|
@@ -0,0 +1,207 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file lib/version.c
+ * @brief versioning and optional feature tests
+ * @author Christian Grothoff
+ */
+#include "internal.h"
+
+
+/**
+ * Obtain the version of this library
+ *
+ * @return static version string, e.g. "0.9.9"
+ * @ingroup specialized
+ */
+const char *
+MHD_get_version (void)
+{
+#ifdef PACKAGE_VERSION
+ return PACKAGE_VERSION;
+#else /* !PACKAGE_VERSION */
+ static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
+ if (0 == ver[0])
+ {
+ int res = MHD_snprintf_ (ver,
+ sizeof(ver),
+ "%x.%x.%x",
+ (((int) MHD_VERSION >> 24) & 0xFF),
+ (((int) MHD_VERSION >> 16) & 0xFF),
+ (((int) MHD_VERSION >> 8) & 0xFF));
+ if ((0 >= res) || (sizeof(ver) <= res))
+ return "0.0.0"; /* Can't return real version*/
+ }
+ return ver;
+#endif /* !PACKAGE_VERSION */
+}
+
+
+/**
+ * Get information about supported MHD features.
+ * Indicate that MHD was compiled with or without support for
+ * particular feature. Some features require additional support
+ * by kernel. Kernel support is not checked by this function.
+ *
+ * @param feature type of requested information
+ * @return #MHD_YES if feature is supported by MHD, #MHD_NO if
+ * feature is not supported or feature is unknown.
+ * @ingroup specialized
+ */
+_MHD_EXTERN enum MHD_Bool
+MHD_is_feature_supported (enum MHD_Feature feature)
+{
+ switch (feature)
+ {
+ case MHD_FEATURE_MESSAGES:
+#ifdef HAVE_MESSAGES
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_TLS:
+#ifdef HTTPS_SUPPORT
+ return MHD_YES;
+#else /* ! HTTPS_SUPPORT */
+ return MHD_NO;
+#endif /* ! HTTPS_SUPPORT */
+ case MHD_FEATURE_HTTPS_CERT_CALLBACK:
+#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
+ return MHD_YES;
+#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
+ return MHD_NO;
+#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
+ case MHD_FEATURE_IPv6:
+#ifdef HAVE_INET6
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_IPv6_ONLY:
+#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_POLL:
+#ifdef HAVE_POLL
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_EPOLL:
+#ifdef EPOLL_SUPPORT
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
+#ifdef HAVE_LISTEN_SHUTDOWN
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_SOCKETPAIR:
+#ifdef _MHD_ITC_SOCKETPAIR
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_TCP_FASTOPEN:
+#ifdef TCP_FASTOPEN
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_BASIC_AUTH:
+#ifdef BAUTH_SUPPORT
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_DIGEST_AUTH:
+#ifdef DAUTH_SUPPORT
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_POSTPROCESSOR:
+#ifdef HAVE_POSTPROCESSOR
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_HTTPS_KEY_PASSWORD:
+#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
+ return MHD_YES;
+#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
+ return MHD_NO;
+#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
+ case MHD_FEATURE_LARGE_FILE:
+#if defined(HAVE_PREAD64) || defined(_WIN32)
+ return MHD_YES;
+#elif defined(HAVE_PREAD)
+ return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
+#elif defined(HAVE_LSEEK64)
+ return MHD_YES;
+#else
+ return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
+#endif
+ case MHD_FEATURE_THREAD_NAMES:
+#if defined(MHD_USE_THREAD_NAME_)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_UPGRADE:
+#if defined(UPGRADE_SUPPORT)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_RESPONSES_SHARED_FD:
+#if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_AUTODETECT_BIND_PORT:
+#ifdef MHD_USE_GETSOCKNAME
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE:
+#if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
+ defined (MSG_NOSIGNAL)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_SENDFILE:
+#ifdef _MHD_HAVE_SENDFILE
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+
+ }
+ return MHD_NO;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/.gitignore
^
|
@@ -43,3 +43,20 @@
*.exe
test_upgrade_tls
test_http_reasons
+/test_daemon.trs
+/test_shutdown_poll_ignore
+/test_shutdown_select_ignore
+/test_str_compare
+/test_str_to_value
+/test_upgrade
+/test_upgrade_ssl
+/test_options
+/test_start_stop
+/test_str_token
+test_shutdown_poll
+test_shutdown_select
+test_md5
+test_sha256
+test_upgrade_large
+test_upgrade_large_tls
+test_postprocessor_md
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/Makefile.am
^
|
@@ -62,24 +62,35 @@
mhd_limits.h mhd_byteorder.h \
sysfdsetsize.c sysfdsetsize.h \
mhd_str.c mhd_str.h \
- mhd_threads.c mhd_threads.h \
- mhd_locks.h \
+ mhd_send.h mhd_send.c \
+ mhd_assert.h \
mhd_sockets.c mhd_sockets.h \
mhd_itc.c mhd_itc.h mhd_itc_types.h \
mhd_compat.c mhd_compat.h \
response.c response.h
+if USE_POSIX_THREADS
+libmicrohttpd_la_SOURCES += \
+ mhd_threads.c mhd_threads.h \
+ mhd_locks.h
+endif
+if USE_W32_THREADS
+libmicrohttpd_la_SOURCES += \
+ mhd_threads.c mhd_threads.h \
+ mhd_locks.h
+endif
+
libmicrohttpd_la_CPPFLAGS = \
- $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \
+ $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) \
-DBUILDING_MHD_LIB=1
libmicrohttpd_la_CFLAGS = \
- $(AM_CFLAGS) $(MHD_LIB_CFLAGS)
+ $(AM_CFLAGS) $(MHD_LIB_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
libmicrohttpd_la_LDFLAGS = \
- $(MHD_LIB_LDFLAGS) \
+ $(MHD_LIB_LDFLAGS) $(MHD_TLS_LIB_LDFLAGS) \
$(W32_MHD_LIB_LDFLAGS) \
-version-info @LIB_VERSION_CURRENT@:@LIB_VERSION_REVISION@:@LIB_VERSION_AGE@
libmicrohttpd_la_LIBADD = \
- $(MHD_LIBDEPS)
+ $(MHD_LIBDEPS) $(MHD_TLS_LIBDEPS)
if HAVE_W32
MHD_DLL_RES_SRC = microhttpd_dll_res.rc
@@ -123,7 +134,9 @@
if ENABLE_DAUTH
libmicrohttpd_la_SOURCES += \
digestauth.c \
- md5.c md5.h
+ mhd_bithelpers.h \
+ md5.c md5.h \
+ sha256.c sha256.h
endif
if ENABLE_BAUTH
@@ -137,22 +150,33 @@
connection_https.c connection_https.h
endif
-
-
check_PROGRAMS = \
test_str_compare \
test_str_to_value \
test_str_token \
test_http_reasons \
- test_shutdown_select \
- test_shutdown_poll \
- test_daemon
+ test_md5 \
+ test_sha256 \
+ test_start_stop \
+ test_daemon \
+ test_postprocessor_md \
+ test_options
if HAVE_POSIX_THREADS
if ENABLE_UPGRADE
- check_PROGRAMS += test_upgrade
+if USE_POSIX_THREADS
+ check_PROGRAMS += test_upgrade test_upgrade_large
+endif
+if USE_W32_THREADS
+ check_PROGRAMS += test_upgrade test_upgrade_large
+endif
if ENABLE_HTTPS
- check_PROGRAMS += test_upgrade_tls
+if USE_POSIX_THREADS
+check_PROGRAMS += test_upgrade_tls test_upgrade_large_tls
+endif
+if USE_W32_THREADS
+check_PROGRAMS += test_upgrade_tls test_upgrade_large_tls
+endif
endif
endif
endif
@@ -166,12 +190,28 @@
TESTS = $(check_PROGRAMS)
-if !HAVE_LISTEN_SHUTDOWN
-XFAIL_TESTS = \
+# Do not test trigger of select by shutdown of listen socket
+# on Cygwin as this ability is deliberately ignored on Cygwin
+# to improve compatibility with core OS.
+if !CYGWIN_TARGET
+if HAVE_POSIX_THREADS
+if HAVE_LISTEN_SHUTDOWN
+check_PROGRAMS += \
test_shutdown_select \
test_shutdown_poll
+else
+check_PROGRAMS += \
+ test_shutdown_select_ignore \
+ test_shutdown_poll_ignore
+endif
+endif
endif
+test_start_stop_SOURCES = \
+ test_start_stop.c
+test_start_stop_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
test_daemon_SOURCES = \
test_daemon.c
test_daemon_LDADD = \
@@ -180,54 +220,89 @@
test_upgrade_SOURCES = \
test_upgrade.c test_helpers.h mhd_sockets.h
test_upgrade_CPPFLAGS = \
- $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
test_upgrade_CFLAGS = \
- $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(GNUTLS_CFLAGS)
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
test_upgrade_LDFLAGS = \
- $(GNUTLS_LDFLAGS)
+ $(MHD_TLS_LIB_LDFLAGS)
test_upgrade_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
+ $(PTHREAD_LIBS)
+
+test_upgrade_large_SOURCES = \
+ test_upgrade_large.c test_helpers.h mhd_sockets.h mhd_sockets.c mhd_itc.h mhd_itc_types.h mhd_itc.c
+test_upgrade_large_CPPFLAGS = \
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
+test_upgrade_large_CFLAGS = \
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+test_upgrade_large_LDFLAGS = \
+ $(MHD_TLS_LIB_LDFLAGS)
+test_upgrade_large_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
$(PTHREAD_LIBS)
test_upgrade_tls_SOURCES = \
test_upgrade.c test_helpers.h mhd_sockets.h
test_upgrade_tls_CPPFLAGS = \
- $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
test_upgrade_tls_CFLAGS = \
- $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(GNUTLS_CFLAGS)
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
test_upgrade_tls_LDFLAGS = \
- $(GNUTLS_LDFLAGS)
+ $(MHD_TLS_LIB_LDFLAGS)
test_upgrade_tls_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
+ $(PTHREAD_LIBS)
+
+test_upgrade_large_tls_SOURCES = \
+ test_upgrade_large.c test_helpers.h mhd_sockets.h mhd_sockets.c mhd_itc.h mhd_itc_types.h mhd_itc.c
+test_upgrade_large_tls_CPPFLAGS = \
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
+test_upgrade_large_tls_CFLAGS = \
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+test_upgrade_large_tls_LDFLAGS = \
+ $(MHD_TLS_LIB_LDFLAGS)
+test_upgrade_large_tls_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
$(PTHREAD_LIBS)
test_postprocessor_SOURCES = \
test_postprocessor.c
test_postprocessor_CPPFLAGS = \
- $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
test_postprocessor_CFLAGS = \
- $(AM_CFLAGS) $(GNUTLS_CFLAGS)
+ $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
test_postprocessor_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
test_postprocessor_amp_SOURCES = \
test_postprocessor_amp.c
test_postprocessor_amp_CPPFLAGS = \
- $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
test_postprocessor_amp_CFLAGS = \
- $(AM_CFLAGS) $(GNUTLS_CFLAGS)
+ $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
test_postprocessor_amp_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
test_postprocessor_large_SOURCES = \
test_postprocessor_large.c
test_postprocessor_large_CPPFLAGS = \
- $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
test_postprocessor_large_CFLAGS = \
- $(AM_CFLAGS) $(GNUTLS_CFLAGS)
+ $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
test_postprocessor_large_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
+test_postprocessor_md_SOURCES = \
+ test_postprocessor_md.c
+test_postprocessor_md_CPPFLAGS = \
+ $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
+test_postprocessor_md_CFLAGS = \
+ $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+
test_shutdown_select_SOURCES = \
test_shutdown_select.c
if USE_POSIX_THREADS
@@ -246,6 +321,24 @@
$(PTHREAD_LIBS)
endif
+test_shutdown_select_ignore_SOURCES = \
+ test_shutdown_select.c
+if USE_POSIX_THREADS
+test_shutdown_select_ignore_CFLAGS = \
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS)
+test_shutdown_select_ignore_LDADD = \
+ $(PTHREAD_LIBS)
+endif
+
+test_shutdown_poll_ignore_SOURCES = \
+ test_shutdown_select.c mhd_threads.h
+if USE_POSIX_THREADS
+test_shutdown_poll_ignore_CFLAGS = \
+ $(AM_CFLAGS) $(PTHREAD_CFLAGS)
+test_shutdown_poll_ignore_LDADD = \
+ $(PTHREAD_LIBS)
+endif
+
test_str_compare_SOURCES = \
test_str.c test_helpers.h mhd_str.c
@@ -258,3 +351,16 @@
test_http_reasons_SOURCES = \
test_http_reasons.c \
reason_phrase.c mhd_str.c mhd_str.h
+
+test_md5_SOURCES = \
+ test_md5.c test_helpers.h \
+ md5.c md5.h mhd_bithelpers.h
+
+test_sha256_SOURCES = \
+ test_sha256.c test_helpers.h \
+ sha256.c sha256.h mhd_bithelpers.h
+
+test_options_SOURCES = \
+ test_options.c
+test_options_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/base64.c
^
|
@@ -9,45 +9,46 @@
#include "base64.h"
static const char base64_digits[] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char *
-BASE64Decode(const char* src)
+BASE64Decode (const char*src)
{
size_t in_len = strlen (src);
- char* dest;
- char* result;
+ char*dest;
+ char*result;
if (in_len % 4)
- {
- /* Wrong base64 string length */
- return NULL;
- }
- result = dest = malloc(in_len / 4 * 3 + 1);
- if (result == NULL)
+ {
+ /* Wrong base64 string length */
+ return NULL;
+ }
+ result = dest = malloc (in_len / 4 * 3 + 1);
+ if (NULL == result)
return NULL; /* out of memory */
- while (*src) {
- char a = base64_digits[(unsigned char)*(src++)];
- char b = base64_digits[(unsigned char)*(src++)];
- char c = base64_digits[(unsigned char)*(src++)];
- char d = base64_digits[(unsigned char)*(src++)];
+ while (*src)
+ {
+ char a = base64_digits[(unsigned char) *(src++)];
+ char b = base64_digits[(unsigned char) *(src++)];
+ char c = base64_digits[(unsigned char) *(src++)];
+ char d = base64_digits[(unsigned char) *(src++)];
*(dest++) = (a << 2) | ((b & 0x30) >> 4);
- if (c == (char)-1)
+ if (c == (char) -1)
break;
*(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
- if (d == (char)-1)
+ if (d == (char) -1)
break;
*(dest++) = ((c & 0x03) << 6) | d;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/base64.h
^
|
@@ -12,6 +12,6 @@
#include "platform.h"
char *
-BASE64Decode(const char* src);
+BASE64Decode (const char*src);
#endif /* !BASE64_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/basicauth.c
^
|
@@ -31,7 +31,7 @@
/**
* Beginning string for any valid Basic authentication header.
*/
-#define _BASIC_BASE "Basic "
+#define _BASIC_BASE "Basic "
/**
@@ -40,65 +40,69 @@
* @param connection The MHD connection structure
* @param password a pointer for the password
* @return NULL if no username could be found, a pointer
- * to the username if found
+ * to the username if found
* @ingroup authentication
*/
char *
MHD_basic_auth_get_username_password (struct MHD_Connection *connection,
- char** password)
+ char**password)
{
const char *header;
char *decode;
const char *separator;
char *user;
- if ( (NULL == (header = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_AUTHORIZATION))) ||
+ if ( (MHD_NO == MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_AUTHORIZATION,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_AUTHORIZATION),
+ &header,
+ NULL)) ||
(0 != strncmp (header,
_BASIC_BASE,
MHD_STATICSTR_LEN_ (_BASIC_BASE))) )
return NULL;
header += MHD_STATICSTR_LEN_ (_BASIC_BASE);
if (NULL == (decode = BASE64Decode (header)))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Error decoding basic authentication\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Error decoding basic authentication.\n"));
#endif
- return NULL;
- }
+ return NULL;
+ }
/* Find user:password pattern */
if (NULL == (separator = strchr (decode,
':')))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG(connection->daemon,
- _("Basic authentication doesn't contain ':' separator\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Basic authentication doesn't contain ':' separator.\n"));
#endif
- free (decode);
- return NULL;
- }
+ free (decode);
+ return NULL;
+ }
if (NULL == (user = strdup (decode)))
- {
- free (decode);
- return NULL;
- }
+ {
+ free (decode);
+ return NULL;
+ }
user[separator - decode] = '\0'; /* cut off at ':' */
if (NULL != password)
+ {
+ *password = strdup (separator + 1);
+ if (NULL == *password)
{
- *password = strdup (separator + 1);
- if (NULL == *password)
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG(connection->daemon,
- _("Failed to allocate memory for password\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to allocate memory for password.\n"));
#endif
- free (decode);
- free (user);
- return NULL;
- }
+ free (decode);
+ free (user);
+ return NULL;
}
+ }
free (decode);
return user;
}
@@ -116,22 +120,22 @@
* @return #MHD_YES on success, #MHD_NO otherwise
* @ingroup authentication
*/
-int
+enum MHD_Result
MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection,
- const char *realm,
- struct MHD_Response *response)
+ const char *realm,
+ struct MHD_Response *response)
{
- int ret;
+ enum MHD_Result ret;
int res;
- size_t hlen = strlen(realm) + strlen("Basic realm=\"\"") + 1;
+ size_t hlen = strlen (realm) + strlen ("Basic realm=\"\"") + 1;
char *header;
- header = (char *) malloc(hlen);
+ header = (char *) malloc (hlen);
if (NULL == header)
{
#ifdef HAVE_MESSAGES
- MHD_DLOG(connection->daemon,
- "Failed to allocate memory for auth header\n");
+ MHD_DLOG (connection->daemon,
+ "Failed to allocate memory for auth header.\n");
#endif /* HAVE_MESSAGES */
return MHD_NO;
}
@@ -139,26 +143,29 @@
hlen,
"Basic realm=\"%s\"",
realm);
- if (res > 0 && (size_t)res < hlen)
+ if ((res > 0) && ((size_t) res < hlen))
ret = MHD_add_response_header (response,
MHD_HTTP_HEADER_WWW_AUTHENTICATE,
header);
else
ret = MHD_NO;
- free(header);
- if (MHD_YES == ret)
+ free (header);
+ if (MHD_NO != ret)
+ {
ret = MHD_queue_response (connection,
- MHD_HTTP_UNAUTHORIZED,
- response);
+ MHD_HTTP_UNAUTHORIZED,
+ response);
+ }
else
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to add Basic auth header\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to add Basic auth header.\n"));
#endif /* HAVE_MESSAGES */
- }
+ }
return ret;
}
+
/* end of basicauth.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/connection.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2020 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,6 @@
* @author Christian Grothoff
* @author Karlson2k (Evgeny Grin)
*/
-
#include "internal.h"
#include "mhd_limits.h"
#include "connection.h"
@@ -32,14 +31,28 @@
#include "response.h"
#include "mhd_mono_clock.h"
#include "mhd_str.h"
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
#include "mhd_locks.h"
+#endif
#include "mhd_sockets.h"
#include "mhd_compat.h"
#include "mhd_itc.h"
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#include <sys/sendfile.h>
+#endif /* MHD_LINUX_SOLARIS_SENDFILE */
+#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#endif /* HAVE_FREEBSD_SENDFILE || HAVE_DARWIN_SENDFILE */
#ifdef HTTPS_SUPPORT
#include "connection_https.h"
#endif /* HTTPS_SUPPORT */
-
+#ifdef HAVE_SYS_PARAM_H
+/* For FreeBSD version identification */
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+#include "mhd_send.h"
/**
* Message to transmit when http 1.1 request is received
@@ -54,7 +67,8 @@
* minimal.
*/
#ifdef HAVE_MESSAGES
-#define REQUEST_TOO_BIG "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
+#define REQUEST_TOO_BIG \
+ "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
#else
#define REQUEST_TOO_BIG ""
#endif
@@ -67,7 +81,8 @@
* minimal.
*/
#ifdef HAVE_MESSAGES
-#define REQUEST_LACKS_HOST "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>"
+#define REQUEST_LACKS_HOST \
+ "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>"
#else
#define REQUEST_LACKS_HOST ""
#endif
@@ -80,7 +95,8 @@
* minimal.
*/
#ifdef HAVE_MESSAGES
-#define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
+#define REQUEST_MALFORMED \
+ "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
#else
#define REQUEST_MALFORMED ""
#endif
@@ -92,252 +108,125 @@
* minimal.
*/
#ifdef HAVE_MESSAGES
-#define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>"
+#define INTERNAL_ERROR \
+ "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>"
#else
#define INTERNAL_ERROR ""
#endif
-/**
- * Add extra debug messages with reasons for closing connections
- * (non-error reasons).
- */
-#define DEBUG_CLOSE MHD_NO
/**
- * Should all data send be printed to stderr?
+ * sendfile() chuck size
*/
-#define DEBUG_SEND_DATA MHD_NO
-
+#define MHD_SENFILE_CHUNK_ (0x20000)
/**
- * Check whether is possible to force push socket buffer content as
- * partial packet.
- * MHD use different buffering logic depending on whether flushing of
- * socket buffer is possible or not.
- * If flushing IS possible than MHD activates extra buffering before
- * sending data to prevent sending partial packets and flush pending
- * data in socket buffer to push last partial packet to client after
- * sending logical completed part of data (for example: after sending
- * full response header or full response message).
- * If flushing IS NOT possible than MHD activates no buffering (no
- * delay sending) when it going to send formed fully completed logical
- * part of data and activate normal buffering after sending.
- * For idled keep-alive connection MHD always activate normal
- * buffering.
- *
- * @param connection connection to check
- * @return #MHD_YES if force push is possible, #MHD_NO otherwise
+ * sendfile() chuck size for thread-per-connection
*/
-static int
-socket_flush_possible(struct MHD_Connection *connection)
-{
-#if defined(TCP_CORK) || defined(TCP_PUSH)
- return MHD_YES;
-#else /* !TCP_CORK && !TCP_PUSH */
- return MHD_NO;
-#endif /* !TCP_CORK && !TCP_PUSH */
-}
-
+#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
+#ifdef HAVE_MESSAGES
/**
- * Activate extra buffering mode on connection socket to prevent
- * sending of partial packets.
- *
- * @param connection connection to be processed
- * @return #MHD_YES on success, #MHD_NO otherwise
- */
-static int
-socket_start_extra_buffering (struct MHD_Connection *connection)
-{
- int res = MHD_NO;
-#if defined(TCP_CORK) || defined(TCP_NOPUSH)
- const MHD_SCKT_OPT_BOOL_ on_val = 1;
-#if defined(TCP_NODELAY)
- const MHD_SCKT_OPT_BOOL_ off_val = 0;
-#endif /* TCP_NODELAY */
- if (!connection)
- return MHD_NO;
-#if defined(TCP_NOPUSH) && !defined(TCP_CORK)
- /* Buffer data before sending */
- res = (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NOPUSH,
- (const void *) &on_val,
- sizeof (on_val)))
- ? MHD_YES : MHD_NO;
-#if defined(TCP_NODELAY)
- /* Enable Nagle's algorithm */
- /* TCP_NODELAY may interfere with TCP_NOPUSH */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_NODELAY */
-#else /* TCP_CORK */
-#if defined(TCP_NODELAY)
- /* Enable Nagle's algorithm */
- /* TCP_NODELAY may prevent enabling TCP_CORK. Resulting buffering mode depends
- solely on TCP_CORK result, so ignoring return code here. */
- (void) setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (const void *) &off_val,
- sizeof (off_val));
-#endif /* TCP_NODELAY */
- /* Send only full packets */
- res = (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_CORK,
- (const void *) &on_val,
- sizeof (on_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_CORK */
-#endif /* TCP_CORK || TCP_NOPUSH */
- return res;
-}
-
-
-/**
- * Activate no buffering mode (no delay sending) on connection socket.
- *
- * @param connection connection to be processed
- * @return #MHD_YES on success, #MHD_NO otherwise
- */
-static int
-socket_start_no_buffering (struct MHD_Connection *connection)
-{
-#if defined(TCP_NODELAY)
- int res = MHD_YES;
- const MHD_SCKT_OPT_BOOL_ on_val = 1;
-#if defined(TCP_CORK) || defined(TCP_NOPUSH)
- const MHD_SCKT_OPT_BOOL_ off_val = 0;
-#endif /* TCP_CORK || TCP_NOPUSH */
-
- if (NULL == connection)
- return MHD_NO;
-#if defined(TCP_CORK)
- /* Allow partial packets */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_CORK,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_CORK */
-#if defined(TCP_NODELAY)
- /* Disable Nagle's algorithm for sending packets without delay */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (const void *) &on_val,
- sizeof (on_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_NODELAY */
-#if defined(TCP_NOPUSH) && !defined(TCP_CORK)
- /* Disable extra buffering */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NOPUSH,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_NOPUSH && !TCP_CORK */
- return res;
-#else /* !TCP_NODELAY */
- return MHD_NO;
-#endif /* !TCP_NODELAY */
+ * Return text description for MHD_ERR_*_ codes
+ * @param mhd_err_code the error code
+ * @return pointer to static string with error description
+ */
+static const char *
+str_conn_error_ (ssize_t mhd_err_code)
+{
+ switch (mhd_err_code)
+ {
+ case MHD_ERR_AGAIN_:
+ return _ ("The operation would block, retry later");
+ case MHD_ERR_CONNRESET_:
+ return _ ("The connection was forcibly closed by remote peer");
+ case MHD_ERR_NOTCONN_:
+ return _ ("The socket is not connected");
+ case MHD_ERR_NOMEM_:
+ return _ ("Not enough system resources to serve the request");
+ case MHD_ERR_BADF_:
+ return _ ("Bad FD value");
+ case MHD_ERR_INVAL_:
+ return _ ("Argument value is invalid");
+ case MHD_ERR_OPNOTSUPP_:
+ return _ ("Argument value is not supported");
+ case MHD_ERR_PIPE_:
+ return _ ("The socket is no longer available for sending");
+ case MHD_ERR_TLS_:
+ return _ ("TLS encryption or decryption error");
+ default:
+ break; /* Mute compiler warning */
+ }
+ if (0 <= mhd_err_code)
+ return _ ("Not an error code");
+
+ mhd_assert (0); /* Should never be reachable */
+ return _ ("Wrong error code value");
}
-/**
- * Activate no buffering mode (no delay sending) on connection socket
- * and push to client data pending in socket buffer.
- *
- * @param connection connection to be processed
- * @return #MHD_YES on success, #MHD_NO otherwise
- */
-static int
-socket_start_no_buffering_flush (struct MHD_Connection *connection)
+#endif /* HAVE_MESSAGES */
+
+/**
+ * Callback for receiving data from the socket.
+ *
+ * @param connection the MHD connection structure
+ * @param other where to write received data to
+ * @param i maximum size of other (in bytes)
+ * @return positive value for number of bytes actually received or
+ * negative value for error number MHD_ERR_xxx_
+ */
+static ssize_t
+recv_param_adapter (struct MHD_Connection *connection,
+ void *other,
+ size_t i)
{
- int res = MHD_YES;
-#if defined(TCP_NOPUSH) && !defined(TCP_CORK)
- const int dummy = 0;
-#endif /* !TCP_CORK */
+ ssize_t ret;
- if (NULL == connection)
- return MHD_NO;
- res = socket_start_no_buffering (connection);
-#if defined(TCP_NOPUSH) && !defined(TCP_CORK)
- /* Force flush data with zero send otherwise Darwin and some BSD systems
- will add 5 seconds delay. Not required with TCP_CORK as switching off
- TCP_CORK always flushes socket buffer. */
- res &= (0 <= MHD_send_ (connection->socket_fd,
- &dummy,
- 0))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_NOPUSH && !TCP_CORK*/
- return res;
-}
-
-
-/**
- * Activate normal buffering mode on connection socket.
- *
- * @param connection connection to be processed
- * @return #MHD_YES on success, #MHD_NO otherwise
- */
-static int
-socket_start_normal_buffering (struct MHD_Connection *connection)
-{
-#if defined(TCP_NODELAY)
- int res = MHD_YES;
- const MHD_SCKT_OPT_BOOL_ off_val = 0;
-#if defined(TCP_CORK)
- MHD_SCKT_OPT_BOOL_ cork_val = 0;
- socklen_t param_size = sizeof (cork_val);
-#endif /* TCP_CORK */
- if (!connection)
- return MHD_NO;
-#if defined(TCP_CORK)
- /* Allow partial packets */
- /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before
- so try to check current value of TCP_CORK to prevent unrequested flushing */
- if ( (0 != getsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_CORK,
- (void*)&cork_val,
- ¶m_size)) ||
- (0 != cork_val))
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_CORK,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
-#elif defined(TCP_NOPUSH)
- /* Disable extra buffering */
- /* No need to check current value as disabling TCP_NOPUSH will not flush partial
- packet if TCP_NOPUSH wasn't enabled before */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NOPUSH,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
-#endif /* TCP_NOPUSH && !TCP_CORK */
- /* Enable Nagle's algorithm for normal buffering */
- res &= (0 == setsockopt (connection->socket_fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (const void *) &off_val,
- sizeof (off_val)))
- ? MHD_YES : MHD_NO;
- return res;
-#else /* !TCP_NODELAY */
- return MHD_NO;
-#endif /* !TCP_NODELAY */
+ if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+ if (i > MHD_SCKT_SEND_MAX_SIZE_)
+ i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
+
+ ret = MHD_recv_ (connection->socket_fd,
+ other,
+ i);
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* Got EAGAIN --- no longer read-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
+ return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EOPNOTSUPP_))
+ return MHD_ERR_OPNOTSUPP_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ENOTCONN_))
+ return MHD_ERR_NOTCONN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EINVAL_))
+ return MHD_ERR_INVAL_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* Treat any other error as a hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#ifdef EPOLL_SUPPORT
+ else if (i > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
+#endif /* EPOLL_SUPPORT */
+ return ret;
}
@@ -350,6 +239,7 @@
* maybe NULL (then just count headers)
* @param iterator_cls extra argument to @a iterator
* @return number of entries iterated over
+ * -1 if connection is NULL.
* @ingroup request
*/
int
@@ -366,20 +256,168 @@
ret = 0;
for (pos = connection->headers_received; NULL != pos; pos = pos->next)
if (0 != (pos->kind & kind))
+ {
+ ret++;
+ if ( (NULL != iterator) &&
+ (MHD_NO == iterator (iterator_cls,
+ pos->kind,
+ pos->header,
+ pos->value)) )
+ return ret;
+ }
+ return ret;
+}
+
+
+/**
+ * Get all of the headers from the request.
+ *
+ * @param connection connection to get values from
+ * @param kind types of values to iterate over, can be a bitmask
+ * @param iterator callback to call on each header;
+ * maybe NULL (then just count headers)
+ * @param iterator_cls extra argument to @a iterator
+ * @return number of entries iterated over,
+ * -1 if connection is NULL.
+ * @ingroup request
+ */
+int
+MHD_get_connection_values_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ MHD_KeyValueIteratorN iterator,
+ void *iterator_cls)
+{
+ int ret;
+ struct MHD_HTTP_Header *pos;
+
+ if (NULL == connection)
+ return -1;
+ ret = 0;
+
+ if (NULL == iterator)
+ for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+ {
+ if (0 != (kind & pos->kind))
+ ret++;
+ }
+ else
+ for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+ if (0 != (kind & pos->kind))
{
- ret++;
- if ( (NULL != iterator) &&
- (MHD_YES != iterator (iterator_cls,
- pos->kind,
- pos->header,
- pos->value)) )
- return ret;
+ ret++;
+ if (MHD_NO == iterator (iterator_cls,
+ pos->kind,
+ pos->header,
+ pos->header_size,
+ pos->value,
+ pos->value_size))
+ return ret;
}
return ret;
}
/**
+ * This function can be used to add an arbitrary entry to connection.
+ * Internal version of #MHD_set_connection_value_n() without checking
+ * of arguments values.
+ *
+ * @param connection the connection for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value, must be zero-terminated
+ * @param key_size number of bytes in @a key (excluding 0-terminator)
+ * @param value the value itself, must be zero-terminated
+ * @param value_size number of bytes in @a value (excluding 0-terminator)
+ * @return #MHD_NO if the operation could not be
+ * performed due to insufficient memory;
+ * #MHD_YES on success
+ * @ingroup request
+ */
+static enum MHD_Result
+MHD_set_connection_value_n_nocheck_ (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char *value,
+ size_t value_size)
+{
+ struct MHD_HTTP_Header *pos;
+
+ pos = MHD_pool_allocate (connection->pool,
+ sizeof (struct MHD_HTTP_Header),
+ true);
+ if (NULL == pos)
+ return MHD_NO;
+ pos->header = (char *) key;
+ pos->header_size = key_size;
+ pos->value = (char *) value;
+ pos->value_size = value_size;
+ pos->kind = kind;
+ pos->next = NULL;
+ /* append 'pos' to the linked list of headers */
+ if (NULL == connection->headers_received_tail)
+ {
+ connection->headers_received = pos;
+ connection->headers_received_tail = pos;
+ }
+ else
+ {
+ connection->headers_received_tail->next = pos;
+ connection->headers_received_tail = pos;
+ }
+ return MHD_YES;
+}
+
+
+/**
+ * This function can be used to add an arbitrary entry to connection.
+ * This function could add entry with binary zero, which is allowed
+ * for #MHD_GET_ARGUMENT_KIND. For other kind on entries it is
+ * recommended to use #MHD_set_connection_value.
+ *
+ * This function MUST only be called from within the
+ * #MHD_AccessHandlerCallback (otherwise, access maybe improperly
+ * synchronized). Furthermore, the client must guarantee that the key
+ * and value arguments are 0-terminated strings that are NOT freed
+ * until the connection is closed. (The easiest way to do this is by
+ * passing only arguments to permanently allocated strings.).
+ *
+ * @param connection the connection for which a
+ * value should be set
+ * @param kind kind of the value
+ * @param key key for the value, must be zero-terminated
+ * @param key_size number of bytes in @a key (excluding 0-terminator)
+ * @param value the value itself, must be zero-terminated
+ * @param value_size number of bytes in @a value (excluding 0-terminator)
+ * @return #MHD_NO if the operation could not be
+ * performed due to insufficient memory;
+ * #MHD_YES on success
+ * @ingroup request
+ */
+enum MHD_Result
+MHD_set_connection_value_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char *value,
+ size_t value_size)
+{
+ if ( (MHD_GET_ARGUMENT_KIND != kind) &&
+ ( ((key ? strlen (key) : 0) != key_size) ||
+ ((value ? strlen (value) : 0) != value_size) ) )
+ return MHD_NO; /* binary zero is allowed only in GET arguments */
+
+ return MHD_set_connection_value_n_nocheck_ (connection,
+ kind,
+ key,
+ key_size,
+ value,
+ value_size);
+}
+
+
+/**
* This function can be used to add an entry to the HTTP headers of a
* connection (so that the #MHD_get_connection_values function will
* return them -- and the `struct MHD_PostProcessor` will also see
@@ -404,35 +442,22 @@
* #MHD_YES on success
* @ingroup request
*/
-int
+enum MHD_Result
MHD_set_connection_value (struct MHD_Connection *connection,
enum MHD_ValueKind kind,
const char *key,
const char *value)
{
- struct MHD_HTTP_Header *pos;
-
- pos = MHD_pool_allocate (connection->pool,
- sizeof (struct MHD_HTTP_Header),
- MHD_YES);
- if (NULL == pos)
- return MHD_NO;
- pos->header = (char *) key;
- pos->value = (char *) value;
- pos->kind = kind;
- pos->next = NULL;
- /* append 'pos' to the linked list of headers */
- if (NULL == connection->headers_received_tail)
- {
- connection->headers_received = pos;
- connection->headers_received_tail = pos;
- }
- else
- {
- connection->headers_received_tail->next = pos;
- connection->headers_received_tail = pos;
- }
- return MHD_YES;
+ return MHD_set_connection_value_n_nocheck_ (connection,
+ kind,
+ key,
+ NULL != key
+ ? strlen (key)
+ : 0,
+ value,
+ NULL != value
+ ? strlen (value)
+ : 0);
}
@@ -451,19 +476,84 @@
enum MHD_ValueKind kind,
const char *key)
{
+ const char *value;
+
+ value = NULL;
+ (void) MHD_lookup_connection_value_n (connection,
+ kind,
+ key,
+ (NULL == key) ? 0 : strlen (key),
+ &value,
+ NULL);
+ return value;
+}
+
+
+/**
+ * Get a particular header value. If multiple
+ * values match the kind, return any one of them.
+ * @note Since MHD_VERSION 0x00096304
+ *
+ * @param connection connection to get values from
+ * @param kind what kind of value are we looking for
+ * @param key the header to look for, NULL to lookup 'trailing' value without a key
+ * @param key_size the length of @a key in bytes
+ * @param[out] value_ptr the pointer to variable, which will be set to found value,
+ * will not be updated if key not found,
+ * could be NULL to just check for presence of @a key
+ * @param[out] value_size_ptr the pointer variable, which will set to found value,
+ * will not be updated if key not found,
+ * could be NULL
+ * @return #MHD_YES if key is found,
+ * #MHD_NO otherwise.
+ * @ingroup request
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_lookup_connection_value_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char **value_ptr,
+ size_t *value_size_ptr)
+{
struct MHD_HTTP_Header *pos;
if (NULL == connection)
- return NULL;
- for (pos = connection->headers_received; NULL != pos; pos = pos->next)
- if ((0 != (pos->kind & kind)) &&
- ( (key == pos->header) ||
- ( (NULL != pos->header) &&
- (NULL != key) &&
- (MHD_str_equal_caseless_(key,
- pos->header)))))
- return pos->value;
- return NULL;
+ return MHD_NO;
+
+ if (NULL == key)
+ {
+ for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+ {
+ if ( (0 != (kind & pos->kind)) &&
+ (NULL == pos->header) )
+ break;
+ }
+ }
+ else
+ {
+ for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+ {
+ if ( (0 != (kind & pos->kind)) &&
+ (key_size == pos->header_size) &&
+ ( (key == pos->header) ||
+ (MHD_str_equal_caseless_bin_n_ (key,
+ pos->header,
+ key_size) ) ) )
+ break;
+ }
+ }
+
+ if (NULL == pos)
+ return MHD_NO;
+
+ if (NULL != value_ptr)
+ *value_ptr = pos->value;
+
+ if (NULL != value_size_ptr)
+ *value_size_ptr = pos->value_size;
+
+ return MHD_YES;
}
@@ -474,6 +564,8 @@
* Case-insensitive match used for header names and tokens.
* @param connection the connection to get values from
* @param header the header name
+ * @param header_len the length of header, not including optional
+ * terminating null-character
* @param token the token to find
* @param token_len the length of token, not including optional
* terminating null-character.
@@ -482,23 +574,32 @@
*/
static bool
MHD_lookup_header_token_ci (const struct MHD_Connection *connection,
- const char *header,
- const char *token,
- size_t token_len)
+ const char *header,
+ size_t header_len,
+ const char *token,
+ size_t token_len)
{
struct MHD_HTTP_Header *pos;
- if (NULL == connection || NULL == header || 0 == header[0] || NULL == token || 0 == token[0])
+ if ((NULL == connection) || (NULL == header) || (0 == header[0]) || (NULL ==
+ token) ||
+ (0 ==
+ token
+ [
+ 0]) )
return false;
+
for (pos = connection->headers_received; NULL != pos; pos = pos->next)
- {
- if ((0 != (pos->kind & MHD_HEADER_KIND)) &&
- ( (header == pos->header) ||
- (MHD_str_equal_caseless_(header,
- pos->header)) ) &&
- (MHD_str_has_token_caseless_ (pos->value, token, token_len)))
- return true;
- }
+ {
+ if ((0 != (pos->kind & MHD_HEADER_KIND)) &&
+ (header_len == pos->header_size) &&
+ ( (header == pos->header) ||
+ (MHD_str_equal_caseless_bin_n_ (header,
+ pos->header,
+ header_len)) ) &&
+ (MHD_str_has_token_caseless_ (pos->value, token, token_len)))
+ return true;
+ }
return false;
}
@@ -509,13 +610,14 @@
* Token could be surrounded by spaces and tabs and delimited by comma.
* Case-insensitive match used for header names and tokens.
* @param c the connection to get values from
- * @param h the header name
+ * @param h the static string of header name
* @param tkn the static string of token to find
* @return true if token is found in specified header,
* false otherwise
*/
#define MHD_lookup_header_s_token_ci(c,h,tkn) \
- MHD_lookup_header_token_ci((c),(h),(tkn),MHD_STATICSTR_LEN_(tkn))
+ MHD_lookup_header_token_ci ((c),(h),MHD_STATICSTR_LEN_ (h), \
+ (tkn),MHD_STATICSTR_LEN_ (tkn))
/**
@@ -523,24 +625,25 @@
* message for this connection?
*
* @param connection connection to test
- * @return 0 if we don't need 100 CONTINUE, 1 if we do
+ * @return false if we don't need 100 CONTINUE, true if we do
*/
-static int
+static bool
need_100_continue (struct MHD_Connection *connection)
{
const char *expect;
- return ( (NULL == connection->response) &&
- (NULL != connection->version) &&
- (MHD_str_equal_caseless_(connection->version,
- MHD_HTTP_VERSION_1_1)) &&
- (NULL != (expect = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_EXPECT))) &&
- (MHD_str_equal_caseless_(expect,
- "100-continue")) &&
- (connection->continue_message_write_offset <
- MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) );
+ return ( (NULL != connection->version) &&
+ (MHD_str_equal_caseless_ (connection->version,
+ MHD_HTTP_VERSION_1_1)) &&
+ (MHD_NO != MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_EXPECT,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_EXPECT),
+ &expect,
+ NULL)) &&
+ (MHD_str_equal_caseless_ (expect,
+ "100-continue")) );
}
@@ -558,24 +661,24 @@
connection->state = MHD_CONNECTION_CLOSED;
connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
if (0 == (daemon->options & MHD_USE_TURBO))
- {
+ {
#ifdef HTTPS_SUPPORT
- /* For TLS connection use shutdown of TLS layer
- * and do not shutdown TCP socket. This give more
- * chances to send TLS closure data to remote side.
- * Closure of TLS layer will be interpreted by
- * remote side as end of transmission. */
- if (0 != (daemon->options & MHD_USE_TLS))
- {
- if (MHD_NO == MHD_tls_connection_shutdown(connection))
- shutdown (connection->socket_fd,
- SHUT_WR);
- }
- else /* Combined with next 'shutdown()'. */
-#endif /* HTTPS_SUPPORT */
- shutdown (connection->socket_fd,
- SHUT_WR);
+ /* For TLS connection use shutdown of TLS layer
+ * and do not shutdown TCP socket. This give more
+ * chances to send TLS closure data to remote side.
+ * Closure of TLS layer will be interpreted by
+ * remote side as end of transmission. */
+ if (0 != (daemon->options & MHD_USE_TLS))
+ {
+ if (! MHD_tls_connection_shutdown (connection))
+ shutdown (connection->socket_fd,
+ SHUT_WR);
}
+ else /* Combined with next 'shutdown()'. */
+#endif /* HTTPS_SUPPORT */
+ shutdown (connection->socket_fd,
+ SHUT_WR);
+ }
}
@@ -595,18 +698,23 @@
struct MHD_Daemon *daemon = connection->daemon;
struct MHD_Response *resp = connection->response;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (connection->pid) );
+#endif /* MHD_USE_THREADS */
+
MHD_connection_mark_closed_ (connection);
if (NULL != resp)
- {
- connection->response = NULL;
- MHD_destroy_response (resp);
- }
+ {
+ connection->response = NULL;
+ MHD_destroy_response (resp);
+ }
if ( (NULL != daemon->notify_completed) &&
(connection->client_aware) )
daemon->notify_completed (daemon->notify_completed_cls,
- connection,
- &connection->client_context,
- termination_code);
+ connection,
+ &connection->client_context,
+ termination_code);
connection->client_aware = false;
}
@@ -628,6 +736,12 @@
struct MHD_Daemon *daemon = connection->daemon;
struct MHD_UpgradeResponseHandle *urh = connection->urh;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
+
if (0 == (daemon->options & MHD_USE_TLS))
return; /* Nothing to do with non-TLS connection. */
@@ -641,44 +755,46 @@
EPOLL_CTL_DEL,
connection->socket_fd,
NULL)) )
- {
- MHD_PANIC (_("Failed to remove FD from epoll set\n"));
- }
+ {
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ }
if (urh->in_eready_list)
- {
- EDLL_remove (daemon->eready_urh_head,
- daemon->eready_urh_tail,
- urh);
- urh->in_eready_list = false;
- }
+ {
+ EDLL_remove (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ urh);
+ urh->in_eready_list = false;
+ }
#endif /* EPOLL_SUPPORT */
if (MHD_INVALID_SOCKET != urh->mhd.socket)
- {
+ {
#if EPOLL_SUPPORT
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
- (0 != epoll_ctl (daemon->epoll_upgrade_fd,
- EPOLL_CTL_DEL,
- urh->mhd.socket,
- NULL)) )
- {
- MHD_PANIC (_("Failed to remove FD from epoll set\n"));
- }
-#endif /* EPOLL_SUPPORT */
- /* Reflect remote disconnect to application by breaking
- * socketpair connection. */
- shutdown (urh->mhd.socket, SHUT_RDWR);
+ if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_DEL,
+ urh->mhd.socket,
+ NULL)) )
+ {
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
}
+#endif /* EPOLL_SUPPORT */
+ /* Reflect remote disconnect to application by breaking
+ * socketpair connection. */
+ shutdown (urh->mhd.socket, SHUT_RDWR);
+ }
/* Socketpair sockets will remain open as they will be
* used with MHD_UPGRADE_ACTION_CLOSE. They will be
- * closed by MHD_cleanup_upgraded_connection_() during
+ * closed by cleanup_upgraded_connection() during
* connection's final cleanup.
*/
}
+
+
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT*/
/**
- * A serious error occured, close the
+ * A serious error occurred, close the
* connection (and notify the application).
*
* @param connection connection to close with error
@@ -686,13 +802,16 @@
*/
static void
connection_close_error (struct MHD_Connection *connection,
- const char *emsg)
+ const char *emsg)
{
#ifdef HAVE_MESSAGES
if (NULL != emsg)
MHD_DLOG (connection->daemon,
+ "%s\n",
emsg);
-#endif
+#else /* ! HAVE_MESSAGES */
+ (void) emsg; /* Mute compiler warning. */
+#endif /* ! HAVE_MESSAGES */
MHD_connection_close_ (connection,
MHD_REQUEST_TERMINATED_WITH_ERROR);
}
@@ -721,59 +840,89 @@
* lock on the response will have been released already
* in this case).
*/
-static int
+static enum MHD_Result
try_ready_normal_body (struct MHD_Connection *connection)
{
ssize_t ret;
struct MHD_Response *response;
response = connection->response;
- if (NULL == response->crc)
- return MHD_YES;
if ( (0 == response->total_size) ||
(connection->response_write_position == response->total_size) )
return MHD_YES; /* 0-byte response is always ready */
+ if (NULL != response->data_iov)
+ {
+ size_t copy_size;
+
+ if (NULL != connection->resp_iov.iov)
+ return MHD_YES;
+ copy_size = response->data_iovcnt * sizeof(MHD_iovec_);
+ connection->resp_iov.iov = MHD_pool_allocate (connection->pool,
+ copy_size,
+ true);
+ if (NULL == connection->resp_iov.iov)
+ {
+ MHD_mutex_unlock_chk_ (&response->mutex);
+ /* not enough memory */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ ("Closing connection (out of memory)."));
+ return MHD_NO;
+ }
+ memcpy (connection->resp_iov.iov,
+ response->data_iov,
+ copy_size);
+ connection->resp_iov.cnt = response->data_iovcnt;
+ connection->resp_iov.sent = 0;
+ return MHD_YES;
+ }
+ if (NULL == response->crc)
+ return MHD_YES;
if ( (response->data_start <=
- connection->response_write_position) &&
+ connection->response_write_position) &&
(response->data_size + response->data_start >
- connection->response_write_position) )
+ connection->response_write_position) )
return MHD_YES; /* response already ready */
-#if LINUX
+#if defined(_MHD_HAVE_SENDFILE)
if (MHD_resp_sender_sendfile == connection->resp_sender)
- {
- /* will use sendfile, no need to bother response crc */
- return MHD_YES;
- }
-#endif
+ {
+ /* will use sendfile, no need to bother response crc */
+ return MHD_YES;
+ }
+#endif /* _MHD_HAVE_SENDFILE */
ret = response->crc (response->crc_cls,
connection->response_write_position,
response->data,
- (size_t) MHD_MIN ((uint64_t)response->data_buffer_size,
- response->total_size -
- connection->response_write_position));
+ (size_t) MHD_MIN ((uint64_t) response->data_buffer_size,
+ response->total_size
+ - connection->response_write_position));
if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
(((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) )
- {
- /* either error or http 1.0 transfer, close socket! */
- response->total_size = connection->response_write_position;
- MHD_mutex_unlock_chk_ (&response->mutex);
- if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret)
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_COMPLETED_OK);
- else
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (application reported error generating data)\n"));
- return MHD_NO;
- }
+ {
+ /* either error or http 1.0 transfer, close socket! */
+ response->total_size = connection->response_write_position;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ if ( ((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret)
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ else
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (application reported error generating data)."));
+ return MHD_NO;
+ }
response->data_start = connection->response_write_position;
response->data_size = ret;
if (0 == ret)
- {
- connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
- MHD_mutex_unlock_chk_ (&response->mutex);
- return MHD_NO;
- }
+ {
+ connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -782,104 +931,113 @@
* Prepare the response buffer of this connection for sending.
* Assumes that the response mutex is already held. If the
* transmission is complete, this function may close the socket (and
- * return MHD_NO).
+ * return #MHD_NO).
*
* @param connection the connection
* @return #MHD_NO if readying the response failed
*/
-static int
+static enum MHD_Result
try_ready_chunked_body (struct MHD_Connection *connection)
{
ssize_t ret;
- char *buf;
struct MHD_Response *response;
- size_t size;
char cbuf[10]; /* 10: max strlen of "%x\r\n" */
int cblen;
response = connection->response;
+ if (NULL == response->crc)
+ return MHD_YES;
if (0 == connection->write_buffer_size)
+ {
+ size_t size;
+
+ size = MHD_pool_get_free (connection->pool);
+ if (size < 128)
{
- size = MHD_MIN (connection->daemon->pool_size,
- 2 * (0xFFFFFF + sizeof(cbuf) + 2));
- do
- {
- size /= 2;
- if (size < 128)
- {
- /* not enough memory */
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (out of memory)\n"));
- return MHD_NO;
- }
- buf = MHD_pool_allocate (connection->pool,
- size,
- MHD_NO);
- }
- while (NULL == buf);
- connection->write_buffer_size = size;
- connection->write_buffer = buf;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ /* not enough memory */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ ("Closing connection (out of memory)."));
+ return MHD_NO;
}
+ if ( (2 * (0xFFFFFF + sizeof(cbuf) + 2)) < size)
+ size = 2 * (0xFFFFFF + sizeof(cbuf) + 2);
+ connection->write_buffer = MHD_pool_allocate (connection->pool,
+ size,
+ false);
+ mhd_assert (NULL != connection->write_buffer);
+ connection->write_buffer_size = size;
+ }
if (0 == response->total_size)
ret = 0; /* response must be empty, don't bother calling crc */
else if ( (response->data_start <=
- connection->response_write_position) &&
- (response->data_start + response->data_size >
- connection->response_write_position) )
- {
- /* difference between response_write_position and data_start is less
- than data_size which is size_t type, no need to check for overflow */
- const size_t data_write_offset
- = (size_t)(connection->response_write_position - response->data_start);
- /* buffer already ready, use what is there for the chunk */
- ret = response->data_size - data_write_offset;
- if ( ((size_t) ret) > connection->write_buffer_size - sizeof (cbuf) - 2 )
- ret = connection->write_buffer_size - sizeof (cbuf) - 2;
- memcpy (&connection->write_buffer[sizeof (cbuf)],
- &response->data[data_write_offset],
- ret);
- }
+ connection->response_write_position) &&
+ (response->data_start + response->data_size >
+ connection->response_write_position) )
+ {
+ /* difference between response_write_position and data_start is less
+ than data_size which is size_t type, no need to check for overflow */
+ const size_t data_write_offset
+ = (size_t) (connection->response_write_position - response->data_start);
+ /* buffer already ready, use what is there for the chunk */
+ ret = response->data_size - data_write_offset;
+ if ( ((size_t) ret) > connection->write_buffer_size - sizeof (cbuf) - 2)
+ ret = connection->write_buffer_size - sizeof (cbuf) - 2;
+ memcpy (&connection->write_buffer[sizeof (cbuf)],
+ &response->data[data_write_offset],
+ ret);
+ }
else
- {
- /* buffer not in range, try to fill it */
- ret = response->crc (response->crc_cls,
- connection->response_write_position,
- &connection->write_buffer[sizeof (cbuf)],
- connection->write_buffer_size - sizeof (cbuf) - 2);
- }
+ {
+ /* buffer not in range, try to fill it */
+ ret = response->crc (response->crc_cls,
+ connection->response_write_position,
+ &connection->write_buffer[sizeof (cbuf)],
+ connection->write_buffer_size - sizeof (cbuf) - 2);
+ }
if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret)
- {
- /* error, close socket! */
- response->total_size = connection->response_write_position;
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (application error generating response)\n"));
- return MHD_NO;
- }
+ {
+ /* error, close socket! */
+ response->total_size = connection->response_write_position;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (application error generating response)."));
+ return MHD_NO;
+ }
if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
(0 == response->total_size) )
- {
- /* end of message, signal other side! */
- strcpy (connection->write_buffer,
- "0\r\n");
- connection->write_buffer_append_offset = 3;
- connection->write_buffer_send_offset = 0;
- response->total_size = connection->response_write_position;
- return MHD_YES;
- }
+ {
+ /* end of message, signal other side! */
+ memcpy (connection->write_buffer,
+ "0\r\n",
+ 3);
+ connection->write_buffer_append_offset = 3;
+ connection->write_buffer_send_offset = 0;
+ response->total_size = connection->response_write_position;
+ return MHD_YES;
+ }
if (0 == ret)
- {
- connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
- return MHD_NO;
- }
+ {
+ connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ return MHD_NO;
+ }
if (ret > 0xFFFFFF)
ret = 0xFFFFFF;
- cblen = MHD_snprintf_(cbuf,
- sizeof (cbuf),
- "%X\r\n",
- (unsigned int) ret);
- EXTRA_CHECK(cblen > 0);
- EXTRA_CHECK(cblen < sizeof(cbuf));
+ cblen = MHD_snprintf_ (cbuf,
+ sizeof (cbuf),
+ "%X\r\n",
+ (unsigned int) ret);
+ mhd_assert (cblen > 0);
+ mhd_assert ((size_t) cblen < sizeof(cbuf));
memcpy (&connection->write_buffer[sizeof (cbuf) - cblen],
cbuf,
cblen);
@@ -909,7 +1067,7 @@
* @return #MHD_YES if (based on the request), a keepalive is
* legal
*/
-static int
+static enum MHD_Result
keepalive_possible (struct MHD_Connection *connection)
{
if (MHD_CONN_MUST_CLOSE == connection->keepalive)
@@ -920,36 +1078,34 @@
(0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
return MHD_NO;
- if (MHD_str_equal_caseless_(connection->version,
- MHD_HTTP_VERSION_1_1))
- {
- if (MHD_lookup_header_s_token_ci (connection,
- MHD_HTTP_HEADER_CONNECTION,
- "upgrade"))
- {
-#ifdef UPGRADE_SUPPORT
- if ( (NULL == connection->response) ||
- (NULL == connection->response->upgrade_handler) )
-#endif /* UPGRADE_SUPPORT */
- return MHD_NO;
- }
- if (MHD_lookup_header_s_token_ci (connection,
- MHD_HTTP_HEADER_CONNECTION,
- "close"))
- return MHD_NO;
+ if (MHD_str_equal_caseless_ (connection->version,
+ MHD_HTTP_VERSION_1_1) &&
+ ( (NULL == connection->response) ||
+ (0 == (connection->response->flags
+ & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) )
+ {
+ if (MHD_lookup_header_s_token_ci (connection,
+ MHD_HTTP_HEADER_CONNECTION,
+ "upgrade"))
+ return MHD_NO;
+ if (MHD_lookup_header_s_token_ci (connection,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close"))
+ return MHD_NO;
+
+ return MHD_YES;
+ }
+ if (MHD_str_equal_caseless_ (connection->version,
+ MHD_HTTP_VERSION_1_0))
+ {
+ if (MHD_lookup_header_s_token_ci (connection,
+ MHD_HTTP_HEADER_CONNECTION,
+ "Keep-Alive"))
return MHD_YES;
- }
- if (MHD_str_equal_caseless_(connection->version,
- MHD_HTTP_VERSION_1_0))
- {
- if (MHD_lookup_header_s_token_ci (connection,
- MHD_HTTP_HEADER_CONNECTION,
- "Keep-Alive"))
- return MHD_YES;
- return MHD_NO;
- }
+ return MHD_NO;
+ }
return MHD_NO;
}
@@ -963,7 +1119,7 @@
*/
static void
get_date_string (char *date,
- size_t date_len)
+ size_t date_len)
{
static const char *const days[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
@@ -974,8 +1130,9 @@
};
struct tm now;
time_t t;
-#if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && !defined(HAVE_GMTIME_R)
- struct tm* pNow;
+#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
+ ! defined(HAVE_GMTIME_R)
+ struct tm*pNow;
#endif
date[0] = 0;
@@ -989,25 +1146,25 @@
&t))
return;
#elif defined(HAVE_GMTIME_R)
- if (NULL == gmtime_r(&t,
- &now))
+ if (NULL == gmtime_r (&t,
+ &now))
return;
#else
- pNow = gmtime(&t);
+ pNow = gmtime (&t);
if (NULL == pNow)
return;
now = *pNow;
#endif
MHD_snprintf_ (date,
- date_len,
- "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
- days[now.tm_wday % 7],
- (unsigned int) now.tm_mday,
- mons[now.tm_mon % 12],
- (unsigned int) (1900 + now.tm_year),
- (unsigned int) now.tm_hour,
- (unsigned int) now.tm_min,
- (unsigned int) now.tm_sec);
+ date_len,
+ "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
+ days[now.tm_wday % 7],
+ (unsigned int) now.tm_mday,
+ mons[now.tm_mon % 12],
+ (unsigned int) (1900 + now.tm_year),
+ (unsigned int) now.tm_hour,
+ (unsigned int) now.tm_min,
+ (unsigned int) now.tm_sec);
}
@@ -1019,28 +1176,64 @@
* minimum necessary at that point.
*
* @param connection the connection
- * @return #MHD_YES on success, #MHD_NO on failure
+ * @param required set to 'true' if grow is required, i.e. connection
+ * will fail if no additional space is granted
+ * @return 'true' on success, 'false' on failure
*/
-static int
-try_grow_read_buffer (struct MHD_Connection *connection)
+static bool
+try_grow_read_buffer (struct MHD_Connection *connection,
+ bool required)
{
- void *buf;
size_t new_size;
+ size_t avail_size;
+ void *rb;
+ avail_size = MHD_pool_get_free (connection->pool);
+ if (0 == avail_size)
+ return false; /* No more space available */
if (0 == connection->read_buffer_size)
- new_size = connection->daemon->pool_size / 2;
+ new_size = avail_size / 2; /* Use half of available buffer for reading */
else
- new_size = connection->read_buffer_size + MHD_BUF_INC_SIZE;
- buf = MHD_pool_reallocate (connection->pool,
- connection->read_buffer,
- connection->read_buffer_size,
- new_size);
- if (NULL == buf)
- return MHD_NO;
+ {
+ size_t grow_size;
+
+ grow_size = avail_size / 8;
+ if (MHD_BUF_INC_SIZE > grow_size)
+ { /* Shortage of space */
+ if (! required)
+ return false; /* Grow is not mandatory, leave some space in pool */
+ else
+ {
+ /* Shortage of space, but grow is mandatory */
+ static const size_t small_inc = MHD_BUF_INC_SIZE / 8;
+ if (small_inc < avail_size)
+ grow_size = small_inc;
+ else
+ grow_size = avail_size;
+ }
+ }
+ new_size = connection->read_buffer_size + grow_size;
+ }
/* we can actually grow the buffer, do it! */
- connection->read_buffer = buf;
+ rb = MHD_pool_reallocate (connection->pool,
+ connection->read_buffer,
+ connection->read_buffer_size,
+ new_size);
+ if (NULL == rb)
+ {
+ /* This should NOT be possible: we just computed 'new_size' so that
+ it should fit. If it happens, somehow our read buffer is not in
+ the right position in the pool, say because someone called
+ MHD_pool_allocate() without 'from_end' set to 'true'? Anyway,
+ should be investigated! (Ideally provide all data from
+ *pool and connection->read_buffer and new_size for debugging). */
+ mhd_assert (0);
+ return false;
+ }
+ connection->read_buffer = rb;
+ mhd_assert (NULL != connection->read_buffer);
connection->read_buffer_size = new_size;
- return MHD_YES;
+ return true;
}
@@ -1053,14 +1246,16 @@
* @param connection the connection
* @return #MHD_YES on success, #MHD_NO on failure (out of memory)
*/
-static int
+static enum MHD_Result
build_header_response (struct MHD_Connection *connection)
{
+ struct MHD_Response *response = connection->response;
size_t size;
size_t off;
struct MHD_HTTP_Header *pos;
char code[256];
char date[128];
+ size_t datelen;
char content_length_buf[128];
size_t content_length_len;
char *data;
@@ -1071,210 +1266,229 @@
bool response_has_close;
bool response_has_keepalive;
const char *have_encoding;
- const char *have_content_length;
- int must_add_close;
- int must_add_chunked_encoding;
- int must_add_keep_alive;
- int must_add_content_length;
+ bool must_add_close;
+ bool must_add_chunked_encoding;
+ bool must_add_keep_alive;
+ bool must_add_content_length;
+ bool may_add_content_length;
- EXTRA_CHECK (NULL != connection->version);
+ mhd_assert (NULL != connection->version);
if (0 == connection->version[0])
- {
- data = MHD_pool_allocate (connection->pool,
- 0,
- MHD_YES);
- connection->write_buffer = data;
- connection->write_buffer_append_offset = 0;
- connection->write_buffer_send_offset = 0;
- connection->write_buffer_size = 0;
- return MHD_YES;
- }
+ {
+ data = MHD_pool_allocate (connection->pool,
+ 0,
+ true);
+ connection->write_buffer = data;
+ connection->write_buffer_append_offset = 0;
+ connection->write_buffer_send_offset = 0;
+ connection->write_buffer_size = 0;
+ return MHD_YES;
+ }
rc = connection->responseCode & (~MHD_ICY_FLAG);
if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
- {
- reason_phrase = MHD_get_reason_phrase_for (rc);
- MHD_snprintf_ (code,
- sizeof (code),
- "%s %u %s\r\n",
- (0 != (connection->responseCode & MHD_ICY_FLAG))
- ? "ICY"
- : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
- connection->version))
- ? MHD_HTTP_VERSION_1_0
- : MHD_HTTP_VERSION_1_1),
- rc,
- reason_phrase);
- off = strlen (code);
- /* estimate size */
- size = off + 2; /* +2 for extra "\r\n" at the end */
- kind = MHD_HEADER_KIND;
- if ( (0 == (connection->daemon->options & MHD_USE_SUPPRESS_DATE_NO_CLOCK)) &&
- (NULL == MHD_get_response_header (connection->response,
- MHD_HTTP_HEADER_DATE)) )
- get_date_string (date,
- sizeof (date));
- else
- date[0] = '\0';
- size += strlen (date);
- }
+ {
+ reason_phrase = MHD_get_reason_phrase_for (rc);
+ off = MHD_snprintf_ (code,
+ sizeof (code),
+ "%s %u %s\r\n",
+ (0 != (connection->responseCode & MHD_ICY_FLAG))
+ ? "ICY"
+ : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
+ connection->version) ||
+ (0 != (connection->response->flags
+ & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) )
+ ? MHD_HTTP_VERSION_1_0
+ : MHD_HTTP_VERSION_1_1),
+ rc,
+ reason_phrase);
+ /* estimate size */
+ size = off + 2; /* +2 for extra "\r\n" at the end */
+ kind = MHD_HEADER_KIND;
+ if ( (0 == (connection->daemon->options
+ & MHD_USE_SUPPRESS_DATE_NO_CLOCK)) &&
+ (NULL == MHD_get_response_header (response,
+ MHD_HTTP_HEADER_DATE)) )
+ get_date_string (date,
+ sizeof (date));
+ else
+ date[0] = '\0';
+ datelen = strlen (date);
+ size += datelen;
+ }
else
- {
- /* 2 bytes for final CRLF of a Chunked-Body */
- size = 2;
- kind = MHD_FOOTER_KIND;
- off = 0;
- }
+ {
+ /* 2 bytes for final CRLF of a Chunked-Body */
+ size = 2;
+ kind = MHD_FOOTER_KIND;
+ off = 0;
+ datelen = 0;
+ }
/* calculate extra headers we need to add, such as 'Connection: close',
first see what was explicitly requested by the application */
- must_add_close = MHD_NO;
- must_add_chunked_encoding = MHD_NO;
- must_add_keep_alive = MHD_NO;
- must_add_content_length = MHD_NO;
+ must_add_close = false;
+ must_add_chunked_encoding = false;
+ must_add_keep_alive = false;
+ must_add_content_length = false;
+ content_length_len = 0; /* Mute compiler warning only */
response_has_close = false;
- response_has_keepalive = false;
switch (connection->state)
- {
- case MHD_CONNECTION_FOOTERS_RECEIVED:
- response_has_close = MHD_check_response_header_s_token_ci (connection->response,
- MHD_HTTP_HEADER_CONNECTION,
- "close");
- response_has_keepalive = MHD_check_response_header_s_token_ci (connection->response,
- MHD_HTTP_HEADER_CONNECTION,
- "Keep-Alive");
- client_requested_close = MHD_lookup_header_s_token_ci (connection,
- MHD_HTTP_HEADER_CONNECTION,
- "close");
+ {
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ response_has_close = MHD_check_response_header_s_token_ci (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
+ response_has_keepalive = MHD_check_response_header_s_token_ci (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "Keep-Alive");
+ client_requested_close = MHD_lookup_header_s_token_ci (connection,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
- if (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY))
- connection->keepalive = MHD_CONN_MUST_CLOSE;
+ if (0 != (response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY))
+ connection->keepalive = MHD_CONN_MUST_CLOSE;
#ifdef UPGRADE_SUPPORT
- else if (NULL != connection->response->upgrade_handler)
- /* If this connection will not be "upgraded", it must be closed. */
- connection->keepalive = MHD_CONN_MUST_CLOSE;
+ else if (NULL != response->upgrade_handler)
+ /* If this connection will not be "upgraded", it must be closed. */
+ connection->keepalive = MHD_CONN_MUST_CLOSE;
#endif /* UPGRADE_SUPPORT */
- /* now analyze chunked encoding situation */
- connection->have_chunked_upload = false;
-
- if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) &&
+ /* now analyze chunked encoding situation */
+ connection->have_chunked_upload = false;
+ have_encoding = MHD_get_response_header (response,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING);
+ if (NULL == have_encoding)
+ may_add_content_length = true;
+ else
+ may_add_content_length = false; /* RFC 7230, Section 3.3.2 forbids header */
+ if ( (MHD_SIZE_UNKNOWN == response->total_size) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
- (! response_has_close) &&
- (! client_requested_close) )
+ (! response_has_close) &&
+ (! client_requested_close) )
+ {
+ /* size is unknown, and close was not explicitly requested;
+ need to either to HTTP 1.1 chunked encoding or
+ close the connection */
+ /* 'close' header doesn't exist yet, see if we need to add one;
+ if the client asked for a close, no need to start chunk'ing */
+ if ( (MHD_NO != keepalive_possible (connection)) &&
+ (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
+ connection->version) ) )
+ {
+ if (NULL == have_encoding)
+ {
+ must_add_chunked_encoding = true;
+ connection->have_chunked_upload = true;
+ }
+ else
{
- /* size is unknown, and close was not explicitly requested;
- need to either to HTTP 1.1 chunked encoding or
- close the connection */
- /* 'close' header doesn't exist yet, see if we need to add one;
- if the client asked for a close, no need to start chunk'ing */
- if ( (MHD_YES == keepalive_possible (connection)) &&
- (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
- connection->version) ) )
- {
- have_encoding = MHD_get_response_header (connection->response,
- MHD_HTTP_HEADER_TRANSFER_ENCODING);
- if (NULL == have_encoding)
- {
- must_add_chunked_encoding = MHD_YES;
- connection->have_chunked_upload = true;
- }
- else if (MHD_str_equal_caseless_ (have_encoding,
- "identity"))
- {
- /* application forced identity encoding, can't do 'chunked' */
- must_add_close = MHD_YES;
- }
- else
- {
- connection->have_chunked_upload = true;
- }
- }
+ if (MHD_str_equal_caseless_ (have_encoding,
+ "identity"))
+ {
+ /* application forced identity encoding, can't do 'chunked' */
+ must_add_close = true;
+ }
else
- {
- /* Keep alive or chunking not possible
- => set close header if not present */
- if (! response_has_close)
- must_add_close = MHD_YES;
- }
+ {
+ connection->have_chunked_upload = true;
+ }
}
+ }
+ else
+ {
+ /* Keep alive or chunking not possible
+ => set close header (we know response_has_close
+ is false here) */
+ must_add_close = true;
+ }
+ }
- /* check for other reasons to add 'close' header */
- if ( ( (client_requested_close) ||
- (connection->read_closed) ||
- (MHD_CONN_MUST_CLOSE == connection->keepalive)) &&
- (! response_has_close) &&
+ /* check for other reasons to add 'close' header */
+ if ( ( (client_requested_close) ||
+ (connection->read_closed) ||
+ (MHD_CONN_MUST_CLOSE == connection->keepalive)) &&
+ (! response_has_close) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
- (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
- must_add_close = MHD_YES;
-
- /* check if we should add a 'content length' header */
- have_content_length = MHD_get_response_header (connection->response,
- MHD_HTTP_HEADER_CONTENT_LENGTH);
-
- /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status
- codes SHOULD NOT have a Content-Length according to spec;
- also chunked encoding / unknown length or CONNECT... */
- if ( (MHD_SIZE_UNKNOWN != connection->response->total_size) &&
- (MHD_HTTP_NO_CONTENT != rc) &&
- (MHD_HTTP_NOT_MODIFIED != rc) &&
- (MHD_HTTP_OK <= rc) &&
- (NULL == have_content_length) &&
- ( (NULL == connection->method) ||
- (! MHD_str_equal_caseless_ (connection->method,
- MHD_HTTP_METHOD_CONNECT)) ) )
- {
- /*
- Here we add a content-length if one is missing; however,
- for 'connect' methods, the responses MUST NOT include a
- content-length header *if* the response code is 2xx (in
- which case we expect there to be no body). Still,
- as we don't know the response code here in some cases, we
- simply only force adding a content-length header if this
- is not a 'connect' or if the response is not empty
- (which is kind of more sane, because if some crazy
- application did return content with a 2xx status code,
- then having a content-length might again be a good idea).
-
- Note that the change from 'SHOULD NOT' to 'MUST NOT' is
- a recent development of the HTTP 1.1 specification.
- */
- content_length_len
- = MHD_snprintf_ (content_length_buf,
- sizeof (content_length_buf),
- MHD_HTTP_HEADER_CONTENT_LENGTH ": " MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
- (MHD_UNSIGNED_LONG_LONG) connection->response->total_size);
- must_add_content_length = MHD_YES;
- }
+ (0 == (response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
+ must_add_close = true;
- /* check for adding keep alive */
- if ( (! response_has_keepalive) &&
- (! response_has_close) &&
- (MHD_NO == must_add_close) &&
- (MHD_CONN_MUST_CLOSE != connection->keepalive) &&
+ /* check if we must add 'close' header because we cannot add content-length
+ because it is forbidden AND we don't have a 'chunked' encoding */
+ if ( (! may_add_content_length) &&
+ (! connection->have_chunked_upload) &&
+ (! response_has_close) )
+ must_add_close = true;
+ /* #MHD_HTTP_NO_CONTENT, #MHD_HTTP_NOT_MODIFIED and 1xx-status
+ codes SHOULD NOT have a Content-Length according to spec;
+ also chunked encoding / unknown length or CONNECT... */
+ if ( (MHD_SIZE_UNKNOWN != response->total_size) &&
+ (MHD_HTTP_NO_CONTENT != rc) &&
+ (MHD_HTTP_NOT_MODIFIED != rc) &&
+ (MHD_HTTP_OK <= rc) &&
+ (NULL == /* this COULD fail if the check in
+ MHD_add_response_header() was bypassed
+ via #MHD_RF_INSANITY_HEADER_CONTENT_LENGTH */
+ MHD_get_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_LENGTH)) &&
+ (may_add_content_length) &&
+ ( (NULL == connection->method) ||
+ (! MHD_str_equal_caseless_ (connection->method,
+ MHD_HTTP_METHOD_CONNECT)) ) )
+ {
+ /*
+ Here we add a content-length if one is missing; however,
+ for 'connect' methods, the responses MUST NOT include a
+ content-length header *if* the response code is 2xx (in
+ which case we expect there to be no body). Still,
+ as we don't know the response code here in some cases, we
+ simply only force adding a content-length header if this
+ is not a 'connect' or if the response is not empty
+ (which is kind of more sane, because if some crazy
+ application did return content with a 2xx status code,
+ then having a content-length might again be a good idea).
+
+ Note that the change from 'SHOULD NOT' to 'MUST NOT' is
+ a recent development of the HTTP 1.1 specification.
+ */
+ content_length_len
+ = MHD_snprintf_ (content_length_buf,
+ sizeof (content_length_buf),
+ MHD_HTTP_HEADER_CONTENT_LENGTH ": "
+ MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
+ (MHD_UNSIGNED_LONG_LONG) response->total_size);
+ must_add_content_length = true;
+ }
+
+ /* check for adding keep alive */
+ if ( (! response_has_keepalive) &&
+ (! response_has_close) &&
+ (! must_add_close) &&
+ (MHD_CONN_MUST_CLOSE != connection->keepalive) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
- (MHD_YES == keepalive_possible (connection)) )
- must_add_keep_alive = MHD_YES;
- break;
- case MHD_CONNECTION_BODY_SENT:
- response_has_keepalive = false;
- break;
- default:
- EXTRA_CHECK (0);
- }
+ (MHD_NO != keepalive_possible (connection)) )
+ must_add_keep_alive = true;
+ break;
+ case MHD_CONNECTION_BODY_SENT:
+ response_has_keepalive = false;
+ break;
+ default:
+ mhd_assert (0);
+ return MHD_NO;
+ }
if (MHD_CONN_MUST_CLOSE != connection->keepalive)
- {
- if ( (must_add_close) || (response_has_close) )
- connection->keepalive = MHD_CONN_MUST_CLOSE;
- else if ( (must_add_keep_alive) || (response_has_keepalive) )
- connection->keepalive = MHD_CONN_USE_KEEPALIVE;
- }
+ {
+ if ( (must_add_close) || (response_has_close) )
+ connection->keepalive = MHD_CONN_MUST_CLOSE;
+ else if ( (must_add_keep_alive) || (response_has_keepalive) )
+ connection->keepalive = MHD_CONN_USE_KEEPALIVE;
+ }
if (must_add_close)
size += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
@@ -1284,93 +1498,102 @@
size += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
if (must_add_content_length)
size += content_length_len;
- EXTRA_CHECK (! (must_add_close && must_add_keep_alive) );
- EXTRA_CHECK (! (must_add_chunked_encoding && must_add_content_length) );
+ mhd_assert (! (must_add_close && must_add_keep_alive) );
+ mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
- for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
- {
- /* TODO: add proper support for excluding "Keep-Alive" token. */
- if ( (pos->kind == kind) &&
- (! ( (MHD_YES == must_add_close) &&
- (response_has_keepalive) &&
- (MHD_str_equal_caseless_(pos->header,
- MHD_HTTP_HEADER_CONNECTION)) &&
- (MHD_str_equal_caseless_(pos->value,
- "Keep-Alive")) ) ) )
- size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */
- }
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
+ {
+ /* TODO: add proper support for excluding "Keep-Alive" token. */
+ if ( (pos->kind == kind) &&
+ (! ( (must_add_close) &&
+ (response_has_keepalive) &&
+ (pos->header_size == MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONNECTION)) &&
+ (MHD_str_equal_caseless_bin_n_ (pos->header,
+ MHD_HTTP_HEADER_CONNECTION,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONNECTION))) &&
+ (MHD_str_equal_caseless_ (pos->value,
+ "Keep-Alive")) ) ) )
+ size += pos->header_size + pos->value_size + 4; /* colon, space, linefeeds */
+ }
/* produce data */
data = MHD_pool_allocate (connection->pool,
size + 1,
- MHD_NO);
+ false);
if (NULL == data)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- "Not enough memory for write!\n");
+ MHD_DLOG (connection->daemon,
+ "Not enough memory for write!\n");
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
- {
- memcpy (data,
- code,
- off);
- }
+ {
+ memcpy (data,
+ code,
+ off);
+ }
if (must_add_close)
- {
- /* we must add the 'Connection: close' header */
- memcpy (&data[off],
- "Connection: close\r\n",
- MHD_STATICSTR_LEN_ ("Connection: close\r\n"));
- off += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
- }
+ {
+ /* we must add the 'Connection: close' header */
+ memcpy (&data[off],
+ "Connection: close\r\n",
+ MHD_STATICSTR_LEN_ ("Connection: close\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
+ }
if (must_add_keep_alive)
- {
- /* we must add the 'Connection: Keep-Alive' header */
- memcpy (&data[off],
- "Connection: Keep-Alive\r\n",
- MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"));
- off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n");
- }
+ {
+ /* we must add the 'Connection: Keep-Alive' header */
+ memcpy (&data[off],
+ "Connection: Keep-Alive\r\n",
+ MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n");
+ }
if (must_add_chunked_encoding)
- {
- /* we must add the 'Transfer-Encoding: chunked' header */
- memcpy (&data[off],
- "Transfer-Encoding: chunked\r\n",
- MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"));
- off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
- }
+ {
+ /* we must add the 'Transfer-Encoding: chunked' header */
+ memcpy (&data[off],
+ "Transfer-Encoding: chunked\r\n",
+ MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"));
+ off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
+ }
if (must_add_content_length)
- {
- /* we must add the 'Content-Length' header */
- memcpy (&data[off],
- content_length_buf,
- content_length_len);
- off += content_length_len;
- }
- for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
- {
- /* TODO: add proper support for excluding "Keep-Alive" token. */
- if ( (pos->kind == kind) &&
- (! ( (MHD_YES == must_add_close) &&
- (response_has_keepalive) &&
- (MHD_str_equal_caseless_(pos->header,
- MHD_HTTP_HEADER_CONNECTION)) &&
- (MHD_str_equal_caseless_(pos->value,
- "Keep-Alive")) ) ) )
- off += MHD_snprintf_ (&data[off],
- size - off,
- "%s: %s\r\n",
- pos->header,
- pos->value);
- }
+ {
+ /* we must add the 'Content-Length' header */
+ memcpy (&data[off],
+ content_length_buf,
+ content_length_len);
+ off += content_length_len;
+ }
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
+ {
+ /* TODO: add proper support for excluding "Keep-Alive" token. */
+ if ( (pos->kind == kind) &&
+ (! ( (must_add_close) &&
+ (response_has_keepalive) &&
+ (pos->header_size == MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONNECTION)) &&
+ (MHD_str_equal_caseless_bin_n_ (pos->header,
+ MHD_HTTP_HEADER_CONNECTION,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONNECTION))) &&
+ (MHD_str_equal_caseless_ (pos->value,
+ "Keep-Alive")) ) ) )
+ off += MHD_snprintf_ (&data[off],
+ size - off,
+ "%s: %s\r\n",
+ pos->header,
+ pos->value);
+ }
if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
- {
- strcpy (&data[off],
- date);
- off += strlen (date);
- }
+ {
+ memcpy (&data[off],
+ date,
+ datelen);
+ off += datelen;
+ }
memcpy (&data[off],
"\r\n",
2);
@@ -1401,49 +1624,76 @@
static void
transmit_error_response (struct MHD_Connection *connection,
unsigned int status_code,
- const char *message)
+ const char *message)
{
struct MHD_Response *response;
+ enum MHD_Result iret;
if (NULL == connection->version)
- {
- /* we were unable to process the full header line, so we don't
- really know what version the client speaks; assume 1.0 */
- connection->version = MHD_HTTP_VERSION_1_0;
- }
+ {
+ /* we were unable to process the full header line, so we don't
+ really know what version the client speaks; assume 1.0 */
+ connection->version = MHD_HTTP_VERSION_1_0;
+ }
connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
connection->read_closed = true;
+ if (0 != connection->read_buffer_size)
+ {
+ /* Read buffer is not needed anymore, discard it
+ * to free some space for error response. */
+ connection->read_buffer = MHD_pool_reallocate (connection->pool,
+ connection->read_buffer,
+ connection->read_buffer_size,
+ 0);
+ connection->read_buffer_size = 0;
+ }
#ifdef HAVE_MESSAGES
MHD_DLOG (connection->daemon,
- _("Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
+ _ (
+ "Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
status_code,
message);
#endif
if (NULL != connection->response)
- {
- MHD_destroy_response (connection->response);
- connection->response = NULL;
- }
+ {
+ MHD_destroy_response (connection->response);
+ connection->response = NULL;
+ }
response = MHD_create_response_from_buffer (strlen (message),
- (void *) message,
- MHD_RESPMEM_PERSISTENT);
- MHD_queue_response (connection,
- status_code,
- response);
- EXTRA_CHECK (NULL != connection->response);
+ (void *) message,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ {
+ /* can't even send a reply, at least close the connection */
+ connection->state = MHD_CONNECTION_CLOSED;
+ return;
+ }
+ iret = MHD_queue_response (connection,
+ status_code,
+ response);
MHD_destroy_response (response);
+ if (MHD_NO == iret)
+ {
+ /* can't even send a reply, at least close the connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to queue response)."));
+ return;
+ }
+ mhd_assert (NULL != connection->response);
/* Do not reuse this connection. */
connection->keepalive = MHD_CONN_MUST_CLOSE;
if (MHD_NO == build_header_response (connection))
- {
- /* oops - close! */
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (failed to create response header)\n"));
- }
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to create response header)."));
+ }
else
- {
- connection->state = MHD_CONNECTION_HEADERS_SENDING;
- }
+ {
+ connection->state = MHD_CONNECTION_HEADERS_SENDING;
+ }
}
@@ -1461,144 +1711,153 @@
/* Do not update states of suspended connection */
if (connection->suspended)
return; /* States will be updated after resume. */
- while (1)
+#ifdef HTTPS_SUPPORT
+ if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+ { /* HTTPS connection. */
+ switch (connection->tls_state)
{
+ case MHD_TLS_CONN_INIT:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ return;
+ case MHD_TLS_CONN_HANDSHAKING:
+ if (0 == gnutls_record_get_direction (connection->tls_session))
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ return;
+ default:
+ break;
+ }
+ }
+#endif /* HTTPS_SUPPORT */
+ while (1)
+ {
#if DEBUG_STATES
- MHD_DLOG (connection->daemon,
- _("In function %s handling connection at state: %s\n"),
- __FUNCTION__,
- MHD_state_to_string (connection->state));
+ MHD_DLOG (connection->daemon,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (connection->state));
#endif
- switch (connection->state)
+ switch (connection->state)
+ {
+ case MHD_CONNECTION_INIT:
+ case MHD_CONNECTION_URL_RECEIVED:
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ /* while reading headers, we always grow the
+ read buffer if needed, no size-check required */
+ if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
+ (! try_grow_read_buffer (connection, true)) )
+ {
+ transmit_error_response (connection,
+ (connection->url != NULL)
+ ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
+ : MHD_HTTP_URI_TOO_LONG,
+ REQUEST_TOO_BIG);
+ continue;
+ }
+ if (! connection->read_closed)
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ mhd_assert (0);
+ break;
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ mhd_assert (0);
+ break;
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_CONNECTION_CONTINUE_SENT:
+ if (connection->read_buffer_offset == connection->read_buffer_size)
+ {
+ const bool internal_poll = (0 != (connection->daemon->options
+ & MHD_USE_INTERNAL_POLLING_THREAD));
+ if ( (! try_grow_read_buffer (connection, true)) &&
+ internal_poll)
{
-#ifdef HTTPS_SUPPORT
- case MHD_TLS_CONNECTION_INIT:
- if (0 == gnutls_record_get_direction (connection->tls_session))
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
- else
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
-#endif /* HTTPS_SUPPORT */
- case MHD_CONNECTION_INIT:
- case MHD_CONNECTION_URL_RECEIVED:
- case MHD_CONNECTION_HEADER_PART_RECEIVED:
- /* while reading headers, we always grow the
- read buffer if needed, no size-check required */
- if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
- (MHD_NO == try_grow_read_buffer (connection)) )
- {
- transmit_error_response (connection,
- (connection->url != NULL)
- ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
- : MHD_HTTP_URI_TOO_LONG,
- REQUEST_TOO_BIG);
- continue;
- }
- if (! connection->read_closed)
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
- else
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
- break;
- case MHD_CONNECTION_HEADERS_RECEIVED:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_HEADERS_PROCESSED:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_CONTINUE_SENDING:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
- case MHD_CONNECTION_CONTINUE_SENT:
- if (connection->read_buffer_offset == connection->read_buffer_size)
- {
- if ((MHD_YES != try_grow_read_buffer (connection)) &&
- (0 != (connection->daemon->options &
- MHD_USE_INTERNAL_POLLING_THREAD)))
- {
- /* failed to grow the read buffer, and the
- client which is supposed to handle the
- received data in a *blocking* fashion
- (in this mode) did not handle the data as
- it was supposed to!
- => we would either have to do busy-waiting
- (on the client, which would likely fail),
- or if we do nothing, we would just timeout
- on the connection (if a timeout is even
- set!).
- Solution: we kill the connection with an error */
- transmit_error_response (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- INTERNAL_ERROR);
- continue;
- }
- }
- if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
- (! connection->read_closed) )
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
- else
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
- break;
- case MHD_CONNECTION_BODY_RECEIVED:
- case MHD_CONNECTION_FOOTER_PART_RECEIVED:
- /* while reading footers, we always grow the
- read buffer if needed, no size-check required */
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
- /* transition to FOOTERS_RECEIVED
- happens in read handler */
- break;
- case MHD_CONNECTION_FOOTERS_RECEIVED:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
- break;
- case MHD_CONNECTION_HEADERS_SENDING:
- /* headers in buffer, keep writing */
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
- case MHD_CONNECTION_HEADERS_SENT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_NORMAL_BODY_READY:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
- case MHD_CONNECTION_NORMAL_BODY_UNREADY:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
- break;
- case MHD_CONNECTION_CHUNKED_BODY_READY:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
- case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
- break;
- case MHD_CONNECTION_BODY_SENT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_FOOTERS_SENDING:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
- break;
- case MHD_CONNECTION_FOOTERS_SENT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_CLOSED:
- connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
- return; /* do nothing, not even reading */
- case MHD_CONNECTION_IN_CLEANUP:
- EXTRA_CHECK (0);
- break;
-#ifdef UPGRADE_SUPPORT
- case MHD_CONNECTION_UPGRADE:
- EXTRA_CHECK (0);
- break;
-#endif /* UPGRADE_SUPPORT */
- default:
- EXTRA_CHECK (0);
+ /* failed to grow the read buffer, and the
+ client which is supposed to handle the
+ received data in a *blocking* fashion
+ (in this mode) did not handle the data as
+ it was supposed to!
+ => we would either have to do busy-waiting
+ (on the client, which would likely fail),
+ or if we do nothing, we would just timeout
+ on the connection (if a timeout is even
+ set!).
+ Solution: we kill the connection with an error */
+ transmit_error_response (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ INTERNAL_ERROR);
+ continue;
}
+ }
+ if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
+ (! connection->read_closed) )
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ else
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_CONNECTION_BODY_RECEIVED:
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ /* while reading footers, we always grow the
+ read buffer if needed, no size-check required */
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ continue;
+ }
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+ /* transition to FOOTERS_RECEIVED
+ happens in read handler */
+ break;
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_CONNECTION_HEADERS_SENDING:
+ /* headers in buffer, keep writing */
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_CONNECTION_HEADERS_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_CONNECTION_NORMAL_BODY_READY:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_CONNECTION_NORMAL_BODY_UNREADY:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_CONNECTION_CHUNKED_BODY_READY:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+ break;
+ case MHD_CONNECTION_BODY_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_CONNECTION_FOOTERS_SENDING:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+ break;
+ case MHD_CONNECTION_FOOTERS_SENT:
+ mhd_assert (0);
+ break;
+ case MHD_CONNECTION_CLOSED:
+ connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+ return; /* do nothing, not even reading */
+#ifdef UPGRADE_SUPPORT
+ case MHD_CONNECTION_UPGRADE:
+ mhd_assert (0);
break;
+#endif /* UPGRADE_SUPPORT */
+ default:
+ mhd_assert (0);
}
+ break;
+ }
}
@@ -1632,22 +1891,21 @@
pos++;
if ( (pos == connection->read_buffer_offset - 1) &&
('\n' != rbuf[pos]) )
+ {
+ /* not found, consider growing... */
+ if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
+ (! try_grow_read_buffer (connection, true)) )
{
- /* not found, consider growing... */
- if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
- (MHD_NO ==
- try_grow_read_buffer (connection)) )
- {
- transmit_error_response (connection,
- (NULL != connection->url)
- ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
- : MHD_HTTP_URI_TOO_LONG,
- REQUEST_TOO_BIG);
- }
- if (line_len)
- *line_len = 0;
- return NULL;
+ transmit_error_response (connection,
+ (NULL != connection->url)
+ ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
+ : MHD_HTTP_URI_TOO_LONG,
+ REQUEST_TOO_BIG);
}
+ if (line_len)
+ *line_len = 0;
+ return NULL;
+ }
if (line_len)
*line_len = pos;
@@ -1671,30 +1929,36 @@
* value should be set
* @param kind kind of the value
* @param key key for the value
+ * @param key_size number of bytes in @a key
* @param value the value itself
+ * @param value_size number of bytes in @a value
* @return #MHD_NO on failure (out of memory), #MHD_YES for success
*/
-static int
+static enum MHD_Result
connection_add_header (struct MHD_Connection *connection,
const char *key,
- const char *value,
- enum MHD_ValueKind kind)
+ size_t key_size,
+ const char *value,
+ size_t value_size,
+ enum MHD_ValueKind kind)
{
if (MHD_NO ==
- MHD_set_connection_value (connection,
- kind,
- key,
- value))
- {
+ MHD_set_connection_value_n (connection,
+ kind,
+ key,
+ key_size,
+ value,
+ value_size))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Not enough memory in pool to allocate header record!\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Not enough memory in pool to allocate header record!\n"));
#endif
- transmit_error_response (connection,
- MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
- REQUEST_TOO_BIG);
- return MHD_NO;
- }
+ transmit_error_response (connection,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -1705,108 +1969,120 @@
* @param connection connection to parse header of
* @return #MHD_YES for success, #MHD_NO for failure (malformed, out of memory)
*/
-static int
+static enum MHD_Result
parse_cookie_header (struct MHD_Connection *connection)
{
const char *hdr;
+ size_t hdr_len;
char *cpy;
char *pos;
char *sce;
char *semicolon;
char *equals;
char *ekill;
+ char *end;
char old;
int quotes;
- hdr = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_COOKIE);
- if (NULL == hdr)
+ if (MHD_NO == MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_COOKIE,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_COOKIE),
+ &hdr,
+ &hdr_len))
return MHD_YES;
cpy = MHD_pool_allocate (connection->pool,
- strlen (hdr) + 1,
- MHD_YES);
+ hdr_len + 1,
+ true);
if (NULL == cpy)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Not enough memory in pool to parse cookies!\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Not enough memory in pool to parse cookies!\n"));
#endif
- transmit_error_response (connection,
- MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
- REQUEST_TOO_BIG);
- return MHD_NO;
- }
+ transmit_error_response (connection,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return MHD_NO;
+ }
memcpy (cpy,
hdr,
- strlen (hdr) + 1);
+ hdr_len);
+ cpy[hdr_len] = '\0';
pos = cpy;
while (NULL != pos)
+ {
+ while (' ' == *pos)
+ pos++; /* skip spaces */
+
+ sce = pos;
+ while ( ((*sce) != '\0') &&
+ ((*sce) != ',') &&
+ ((*sce) != ';') &&
+ ((*sce) != '=') )
+ sce++;
+ /* remove tailing whitespace (if any) from key */
+ ekill = sce - 1;
+ while ( (*ekill == ' ') &&
+ (ekill >= pos) )
+ *(ekill--) = '\0';
+ old = *sce;
+ *sce = '\0';
+ if (old != '=')
{
- while (' ' == *pos)
- pos++; /* skip spaces */
-
- sce = pos;
- while ( ((*sce) != '\0') &&
- ((*sce) != ',') &&
- ((*sce) != ';') &&
- ((*sce) != '=') )
- sce++;
- /* remove tailing whitespace (if any) from key */
- ekill = sce - 1;
- while ( (*ekill == ' ') &&
- (ekill >= pos) )
- *(ekill--) = '\0';
- old = *sce;
- *sce = '\0';
- if (old != '=')
- {
- /* value part omitted, use empty string... */
- if (MHD_NO ==
- connection_add_header (connection,
- pos,
- "",
- MHD_COOKIE_KIND))
- return MHD_NO;
- if (old == '\0')
- break;
- pos = sce + 1;
- continue;
- }
- equals = sce + 1;
- quotes = 0;
- semicolon = equals;
- while ( ('\0' != semicolon[0]) &&
- ( (0 != quotes) ||
- ( (';' != semicolon[0]) &&
- (',' != semicolon[0]) ) ) )
- {
- if ('"' == semicolon[0])
- quotes = (quotes + 1) & 1;
- semicolon++;
- }
- if ('\0' == semicolon[0])
- semicolon = NULL;
- if (NULL != semicolon)
- {
- semicolon[0] = '\0';
- semicolon++;
- }
- /* remove quotes */
- if ( ('"' == equals[0]) &&
- ('"' == equals[strlen (equals) - 1]) )
- {
- equals[strlen (equals) - 1] = '\0';
- equals++;
- }
+ /* value part omitted, use empty string... */
if (MHD_NO ==
- connection_add_header (connection,
- pos,
- equals,
- MHD_COOKIE_KIND))
+ connection_add_header (connection,
+ pos,
+ ekill - pos + 1,
+ "",
+ 0,
+ MHD_COOKIE_KIND))
return MHD_NO;
- pos = semicolon;
- }
+ if (old == '\0')
+ break;
+ pos = sce + 1;
+ continue;
+ }
+ equals = sce + 1;
+ quotes = 0;
+ semicolon = equals;
+ while ( ('\0' != semicolon[0]) &&
+ ( (0 != quotes) ||
+ ( (';' != semicolon[0]) &&
+ (',' != semicolon[0]) ) ) )
+ {
+ if ('"' == semicolon[0])
+ quotes = (quotes + 1) & 1;
+ semicolon++;
+ }
+ end = semicolon;
+ if ('\0' == semicolon[0])
+ semicolon = NULL;
+ if (NULL != semicolon)
+ {
+ semicolon[0] = '\0';
+ semicolon++;
+ }
+ /* remove quotes */
+ if ( ('"' == equals[0]) &&
+ ('"' == end[-1]) )
+ {
+ equals++;
+ end--;
+ *end = '\0';
+ }
+ if (MHD_NO ==
+ connection_add_header (connection,
+ pos,
+ ekill - pos + 1,
+ equals,
+ end - equals,
+ MHD_COOKIE_KIND))
+ return MHD_NO;
+ pos = semicolon;
+ }
return MHD_YES;
}
@@ -1819,7 +2095,7 @@
* @param line_len length of the first @a line
* @return #MHD_YES if the line is ok, #MHD_NO if it is malformed
*/
-static int
+static enum MHD_Result
parse_initial_message_line (struct MHD_Connection *connection,
char *line,
size_t line_len)
@@ -1841,63 +2117,80 @@
/* Skip any spaces. Not required by standard but allow
to be more tolerant. */
while ( (' ' == uri[0]) &&
- ( (size_t)(uri - line) < line_len) )
+ ( (size_t) (uri - line) < line_len) )
uri++;
- if ((size_t)(uri - line) == line_len)
+ if ((size_t) (uri - line) == line_len)
+ {
+ /* No URI and no http version given */
+ curi = "";
+ uri = NULL;
+ connection->version = "";
+ args = NULL;
+ }
+ else
+ {
+ size_t uri_len;
+ curi = uri;
+ /* Search from back to accept malformed URI with space */
+ http_version = line + line_len - 1;
+ /* Skip any trailing spaces */
+ while ( (' ' == http_version[0]) &&
+ (http_version > uri) )
+ http_version--;
+ /* Find first space in reverse direction */
+ while ( (' ' != http_version[0]) &&
+ (http_version > uri) )
+ http_version--;
+ if (http_version > uri)
+ {
+ /* http_version points to character before HTTP version string */
+ http_version[0] = '\0';
+ connection->version = http_version + 1;
+ uri_len = http_version - uri;
+ }
+ else
{
- curi = "";
- uri = NULL;
connection->version = "";
- args = NULL;
+ uri_len = line_len - (uri - line);
}
- else
+ /* check for spaces in URI if we are "strict" */
+ if ( (1 <= daemon->strict_for_client) &&
+ (NULL != memchr (uri,
+ ' ',
+ uri_len)) )
{
- curi = uri;
- /* Search from back to accept misformed URI with space */
- http_version = line + line_len - 1;
- /* Skip any trailing spaces */
- while ( (' ' == http_version[0]) &&
- (http_version > uri) )
- http_version--;
- /* Find first space in reverse direction */
- while ( (' ' != http_version[0]) &&
- (http_version > uri) )
- http_version--;
- if (http_version > uri)
- {
- http_version[0] = '\0';
- connection->version = http_version + 1;
- args = memchr (uri,
- '?',
- http_version - uri);
- }
- else
- {
- connection->version = "";
- args = memchr (uri,
- '?',
- line_len - (uri - line));
- }
+ /* space exists in URI and we are supposed to be strict, reject */
+ return MHD_NO;
}
+
+ args = memchr (uri,
+ '?',
+ uri_len);
+ }
+
+ /* log callback before we modify URI *or* args */
if (NULL != daemon->uri_log_callback)
- {
- connection->client_aware = true;
- connection->client_context
- = daemon->uri_log_callback (daemon->uri_log_callback_cls,
- curi,
- connection);
- }
+ {
+ connection->client_aware = true;
+ connection->client_context
+ = daemon->uri_log_callback (daemon->uri_log_callback_cls,
+ uri,
+ connection);
+ }
+
if (NULL != args)
- {
- args[0] = '\0';
- args++;
- /* note that this call clobbers 'args' */
- MHD_parse_arguments_ (connection,
- MHD_GET_ARGUMENT_KIND,
- args,
- &connection_add_header,
- &unused_num_headers);
- }
+ {
+ args[0] = '\0';
+ args++;
+ /* note that this call clobbers 'args' */
+ MHD_parse_arguments_ (connection,
+ MHD_GET_ARGUMENT_KIND,
+ args,
+ &connection_add_header,
+ &unused_num_headers);
+ }
+
+ /* unescape URI *after* searching for arguments and log callback */
if (NULL != uri)
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
@@ -1917,6 +2210,7 @@
static void
call_connection_handler (struct MHD_Connection *connection)
{
+ struct MHD_Daemon *daemon = connection->daemon;
size_t processed;
if (NULL != connection->response)
@@ -1924,24 +2218,24 @@
processed = 0;
connection->client_aware = true;
if (MHD_NO ==
- connection->daemon->default_handler (connection->daemon->default_handler_cls,
- connection,
- connection->url,
- connection->method,
- connection->version,
- NULL,
- &processed,
- &connection->client_context))
- {
- /* serious internal error, close connection */
- CONNECTION_CLOSE_ERROR (connection,
- _("Application reported internal error, closing connection.\n"));
- return;
- }
+ daemon->default_handler (daemon->default_handler_cls,
+ connection,
+ connection->url,
+ connection->method,
+ connection->version,
+ NULL,
+ &processed,
+ &connection->client_context))
+ {
+ /* serious internal error, close connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Application reported internal error, closing connection."));
+ return;
+ }
}
-
/**
* Call the handler of the application for this
* connection. Handles chunking of the upload
@@ -1952,211 +2246,233 @@
static void
process_request_body (struct MHD_Connection *connection)
{
+ struct MHD_Daemon *daemon = connection->daemon;
size_t available;
int instant_retry;
char *buffer_head;
if (NULL != connection->response)
- return; /* already queued a response */
+ {
+ /* already queued a response, discard remaining upload
+ (but not more, there might be another request after it) */
+ size_t purge;
+
+ purge = (size_t) MHD_MIN (connection->remaining_upload_size,
+ (uint64_t) connection->read_buffer_offset);
+ connection->remaining_upload_size -= purge;
+ if (connection->read_buffer_offset > purge)
+ memmove (connection->read_buffer,
+ &connection->read_buffer[purge],
+ connection->read_buffer_offset - purge);
+ connection->read_buffer_offset -= purge;
+ return;
+ }
buffer_head = connection->read_buffer;
available = connection->read_buffer_offset;
do
- {
- size_t to_be_processed;
- size_t left_unprocessed;
- size_t processed_size;
-
- instant_retry = MHD_NO;
- if ( (connection->have_chunked_upload) &&
- (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
+ {
+ size_t to_be_processed;
+ size_t left_unprocessed;
+ size_t processed_size;
+
+ instant_retry = MHD_NO;
+ if ( (connection->have_chunked_upload) &&
+ (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
+ {
+ if ( (connection->current_chunk_offset ==
+ connection->current_chunk_size) &&
+ (0LLU != connection->current_chunk_offset) &&
+ (available >= 2) )
+ {
+ size_t i;
+ /* skip new line at the *end* of a chunk */
+ i = 0;
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ i++; /* skip 1st part of line feed */
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ i++; /* skip 2nd part of line feed */
+ if (0 == i)
{
- if ( (connection->current_chunk_offset == connection->current_chunk_size) &&
- (0LLU != connection->current_chunk_offset) &&
- (available >= 2) )
- {
- size_t i;
- /* skip new line at the *end* of a chunk */
- i = 0;
- if ( ('\r' == buffer_head[i]) ||
- ('\n' == buffer_head[i]) )
- i++; /* skip 1st part of line feed */
- if ( ('\r' == buffer_head[i]) ||
- ('\n' == buffer_head[i]) )
- i++; /* skip 2nd part of line feed */
- if (0 == i)
- {
- /* malformed encoding */
- CONNECTION_CLOSE_ERROR (connection,
- _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
- return;
- }
- available -= i;
- buffer_head += i;
- connection->current_chunk_offset = 0;
- connection->current_chunk_size = 0;
- }
- if (connection->current_chunk_offset <
- connection->current_chunk_size)
- {
- uint64_t cur_chunk_left;
- /* we are in the middle of a chunk, give
- as much as possible to the client (without
- crossing chunk boundaries) */
- cur_chunk_left
- = connection->current_chunk_size - connection->current_chunk_offset;
- if (cur_chunk_left > available)
- to_be_processed = available;
- else
- { /* cur_chunk_left <= (size_t)available */
- to_be_processed = (size_t)cur_chunk_left;
- if (available > to_be_processed)
- instant_retry = MHD_YES;
- }
- }
- else
- {
- size_t i;
- size_t end_size;
- bool malformed;
-
- /* we need to read chunk boundaries */
- i = 0;
- while (i < available)
- {
- if ( ('\r' == buffer_head[i]) ||
- ('\n' == buffer_head[i]) ||
- (';' == buffer_head[i]) )
- break;
- i++;
- if (i >= 16)
- break;
- }
- end_size = i;
- /* find beginning of CRLF (skip over chunk extensions) */
- if (';' == buffer_head[i])
- {
- while (i < available)
- {
- if ( ('\r' == buffer_head[i]) ||
- ('\n' == buffer_head[i]) )
- break;
- i++;
- }
- }
- /* take '\n' into account; if '\n' is the unavailable
- character, we will need to wait until we have it
- before going further */
- if ( (i + 1 >= available) &&
- ! ( (1 == i) &&
- (2 == available) &&
- ('0' == buffer_head[0]) ) )
- break; /* need more data... */
- i++;
- malformed = (end_size >= 16);
- if (! malformed)
- {
- size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head,
- end_size,
- &connection->current_chunk_size);
- malformed = (end_size != num_dig);
- }
- if (malformed)
- {
- /* malformed encoding */
- CONNECTION_CLOSE_ERROR (connection,
- _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
- return;
- }
- /* skip 2nd part of line feed */
- if ( (i < available) &&
- ( ('\r' == buffer_head[i]) ||
- ('\n' == buffer_head[i]) ) )
- i++;
-
- buffer_head += i;
- available -= i;
- connection->current_chunk_offset = 0;
-
- if (available > 0)
- instant_retry = MHD_YES;
- if (0LLU == connection->current_chunk_size)
- {
- connection->remaining_upload_size = 0;
- break;
- }
- continue;
- }
+ /* malformed encoding */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Received malformed HTTP request (bad chunked encoding). Closing connection."));
+ return;
+ }
+ available -= i;
+ buffer_head += i;
+ connection->current_chunk_offset = 0;
+ connection->current_chunk_size = 0;
+ }
+ if (connection->current_chunk_offset <
+ connection->current_chunk_size)
+ {
+ uint64_t cur_chunk_left;
+ /* we are in the middle of a chunk, give
+ as much as possible to the client (without
+ crossing chunk boundaries) */
+ cur_chunk_left
+ = connection->current_chunk_size - connection->current_chunk_offset;
+ if (cur_chunk_left > available)
+ to_be_processed = available;
+ else
+ { /* cur_chunk_left <= (size_t)available */
+ to_be_processed = (size_t) cur_chunk_left;
+ if (available > to_be_processed)
+ instant_retry = MHD_YES;
}
+ }
else
+ {
+ size_t i;
+ size_t end_size;
+ bool malformed;
+
+ /* we need to read chunk boundaries */
+ i = 0;
+ while (i < available)
{
- /* no chunked encoding, give all to the client */
- if ( (0 != connection->remaining_upload_size) &&
- (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
- (connection->remaining_upload_size < available) )
- {
- to_be_processed = (size_t)connection->remaining_upload_size;
- }
- else
- {
- /**
- * 1. no chunked encoding, give all to the client
- * 2. client may send large chunked data, but only a smaller part is available at one time.
- */
- to_be_processed = available;
- }
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) ||
+ (';' == buffer_head[i]) )
+ break;
+ i++;
+ if (i >= 16)
+ break;
}
- left_unprocessed = to_be_processed;
- connection->client_aware = true;
- if (MHD_NO ==
- connection->daemon->default_handler (connection->daemon->default_handler_cls,
- connection,
- connection->url,
- connection->method,
- connection->version,
- buffer_head,
- &left_unprocessed,
- &connection->client_context))
+ end_size = i;
+ /* find beginning of CRLF (skip over chunk extensions) */
+ if (';' == buffer_head[i])
{
- /* serious internal error, close connection */
+ while (i < available)
+ {
+ if ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) )
+ break;
+ i++;
+ }
+ }
+ /* take '\n' into account; if '\n' is the unavailable
+ character, we will need to wait until we have it
+ before going further */
+ if ( (i + 1 >= available) &&
+ ! ( (1 == i) &&
+ (2 == available) &&
+ ('0' == buffer_head[0]) ) )
+ break; /* need more data... */
+ i++;
+ malformed = (end_size >= 16);
+ if (! malformed)
+ {
+ size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head,
+ end_size,
+ &connection->
+ current_chunk_size);
+ malformed = (end_size != num_dig);
+ }
+ if (malformed)
+ {
+ /* malformed encoding */
CONNECTION_CLOSE_ERROR (connection,
- _("Application reported internal error, closing connection.\n"));
+ _ (
+ "Received malformed HTTP request (bad chunked encoding). Closing connection."));
return;
}
- if (left_unprocessed > to_be_processed)
- mhd_panic (mhd_panic_cls,
- __FILE__,
- __LINE__
+ /* skip 2nd part of line feed */
+ if ( (i < available) &&
+ ( ('\r' == buffer_head[i]) ||
+ ('\n' == buffer_head[i]) ) )
+ i++;
+
+ buffer_head += i;
+ available -= i;
+ connection->current_chunk_offset = 0;
+
+ if (available > 0)
+ instant_retry = MHD_YES;
+ if (0LLU == connection->current_chunk_size)
+ {
+ connection->remaining_upload_size = 0;
+ break;
+ }
+ continue;
+ }
+ }
+ else
+ {
+ /* no chunked encoding, give all to the client */
+ if ( (0 != connection->remaining_upload_size) &&
+ (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
+ (connection->remaining_upload_size < available) )
+ {
+ to_be_processed = (size_t) connection->remaining_upload_size;
+ }
+ else
+ {
+ /**
+ * 1. no chunked encoding, give all to the client
+ * 2. client may send large chunked data, but only a smaller part is available at one time.
+ */
+ to_be_processed = available;
+ }
+ }
+ left_unprocessed = to_be_processed;
+ connection->client_aware = true;
+ if (MHD_NO ==
+ daemon->default_handler (daemon->default_handler_cls,
+ connection,
+ connection->url,
+ connection->method,
+ connection->version,
+ buffer_head,
+ &left_unprocessed,
+ &connection->client_context))
+ {
+ /* serious internal error, close connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Application reported internal error, closing connection."));
+ return;
+ }
+ if (left_unprocessed > to_be_processed)
+ mhd_panic (mhd_panic_cls,
+ __FILE__,
+ __LINE__
#ifdef HAVE_MESSAGES
- , _("libmicrohttpd API violation")
+ , _ ("libmicrohttpd API violation.\n")
#else
- , NULL
+ , NULL
#endif
- );
- if (0 != left_unprocessed)
- {
- instant_retry = MHD_NO; /* client did not process everything */
-#ifdef HAVE_MESSAGES
- /* client did not process all upload data, complain if
- the setup was incorrect, which may prevent us from
- handling the rest of the request */
- if ( (0 != (connection->daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
- (! connection->suspended) )
- MHD_DLOG (connection->daemon,
- _("WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
+ );
+ if (0 != left_unprocessed)
+ {
+ instant_retry = MHD_NO; /* client did not process everything */
+#ifdef HAVE_MESSAGES
+ /* client did not process all upload data, complain if
+ the setup was incorrect, which may prevent us from
+ handling the rest of the request */
+ if ( (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
+ (! connection->suspended) )
+ MHD_DLOG (daemon,
+ _ (
+ "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
#endif
- }
- processed_size = to_be_processed - left_unprocessed;
- if (connection->have_chunked_upload)
- connection->current_chunk_offset += processed_size;
- /* dh left "processed" bytes in buffer for next time... */
- buffer_head += processed_size;
- available -= processed_size;
- if (MHD_SIZE_UNKNOWN != connection->remaining_upload_size)
- connection->remaining_upload_size -= processed_size;
}
- while (MHD_YES == instant_retry);
- if (available > 0)
+ processed_size = to_be_processed - left_unprocessed;
+ if (connection->have_chunked_upload)
+ connection->current_chunk_offset += processed_size;
+ /* dh left "processed" bytes in buffer for next time... */
+ buffer_head += processed_size;
+ available -= processed_size;
+ if (MHD_SIZE_UNKNOWN != connection->remaining_upload_size)
+ connection->remaining_upload_size -= processed_size;
+ }
+ while (MHD_NO != instant_retry);
+ if ( (available > 0) &&
+ (buffer_head != connection->read_buffer) )
memmove (connection->read_buffer,
buffer_head,
available);
@@ -2165,101 +2481,6 @@
/**
- * Try reading data from the socket into the read buffer of the
- * connection.
- *
- * @param connection connection we're processing
- * @return #MHD_YES if something changed,
- * #MHD_NO if we were interrupted or if
- * no space was available
- */
-static int
-do_read (struct MHD_Connection *connection)
-{
- ssize_t bytes_read;
-
- if (connection->read_buffer_size == connection->read_buffer_offset)
- return MHD_NO;
- bytes_read = connection->recv_cls (connection,
- &connection->read_buffer
- [connection->read_buffer_offset],
- connection->read_buffer_size -
- connection->read_buffer_offset);
- if (bytes_read < 0)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
- MHD_SCKT_ERR_IS_EAGAIN_ (err))
- return MHD_NO;
- if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return MHD_NO;
- }
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return MHD_YES;
- }
- if (0 == bytes_read)
- {
- /* other side closed connection; RFC 2616, section 8.1.4 suggests
- we should then shutdown ourselves as well. */
- connection->read_closed = true;
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_CLIENT_ABORT);
- return MHD_YES;
- }
- connection->read_buffer_offset += bytes_read;
- return MHD_YES;
-}
-
-
-/**
- * Try writing data to the socket from the
- * write buffer of the connection.
- *
- * @param connection connection we're processing
- * @return #MHD_YES if something changed,
- * #MHD_NO if we were interrupted
- */
-static int
-do_write (struct MHD_Connection *connection)
-{
- ssize_t ret;
- size_t max;
-
- max = connection->write_buffer_append_offset - connection->write_buffer_send_offset;
- ret = connection->send_cls (connection,
- &connection->write_buffer
- [connection->write_buffer_send_offset],
- max);
-
- if (ret < 0)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
- MHD_SCKT_ERR_IS_EAGAIN_ (err))
- return MHD_NO;
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return MHD_YES;
- }
-#if DEBUG_SEND_DATA
- fprintf (stderr,
- _("Sent response: `%.*s'\n"),
- ret,
- &connection->write_buffer[connection->write_buffer_send_offset]);
-#endif
- /* only increment if this wasn't a "sendfile" transmission without
- buffer involvement! */
- if (0 != max)
- connection->write_buffer_send_offset += ret;
- return MHD_YES;
-}
-
-
-/**
* Check if we are done sending the write-buffer.
* If so, transition into "next_state".
*
@@ -2267,18 +2488,20 @@
* @param next_state the next state to transition to
* @return #MHD_NO if we are not done, #MHD_YES if we are
*/
-static int
+static enum MHD_Result
check_write_done (struct MHD_Connection *connection,
enum MHD_CONNECTION_STATE next_state)
{
- if (connection->write_buffer_append_offset !=
- connection->write_buffer_send_offset)
+ if ( (connection->write_buffer_append_offset !=
+ connection->write_buffer_send_offset)
+ /* || data_in_tls_buffers == true */
+ )
return MHD_NO;
connection->write_buffer_append_offset = 0;
connection->write_buffer_send_offset = 0;
connection->state = next_state;
MHD_pool_reallocate (connection->pool,
- connection->write_buffer,
+ connection->write_buffer,
connection->write_buffer_size,
0);
connection->write_buffer = NULL;
@@ -2296,7 +2519,7 @@
* @param line line from the header to process
* @return #MHD_YES on success, #MHD_NO on error (malformed @a line)
*/
-static int
+static enum MHD_Result
process_header_line (struct MHD_Connection *connection,
char *line)
{
@@ -2305,28 +2528,29 @@
/* line should be normal header line, find colon */
colon = strchr (line, ':');
if (NULL == colon)
- {
- /* error in header line, die hard */
- CONNECTION_CLOSE_ERROR (connection,
- _("Received malformed line (no colon). Closing connection.\n"));
- return MHD_NO;
- }
+ {
+ /* error in header line, die hard */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Received malformed line (no colon). Closing connection."));
+ return MHD_NO;
+ }
if (-1 >= connection->daemon->strict_for_client)
- {
- /* check for whitespace before colon, which is not allowed
- by RFC 7230 section 3.2.4; we count space ' ' and
- tab '\t', but not '\r\n' as those would have ended the line. */
- const char *white;
-
- white = strchr (line, ' ');
- if ( (NULL != white) &&
- (white < colon) )
- return MHD_NO;
- white = strchr (line, '\t');
- if ( (NULL != white) &&
- (white < colon) )
- return MHD_NO;
- }
+ {
+ /* check for whitespace before colon, which is not allowed
+ by RFC 7230 section 3.2.4; we count space ' ' and
+ tab '\t', but not '\r\n' as those would have ended the line. */
+ const char *white;
+
+ white = strchr (line, ' ');
+ if ( (NULL != white) &&
+ (white < colon) )
+ return MHD_NO;
+ white = strchr (line, '\t');
+ if ( (NULL != white) &&
+ (white < colon) )
+ return MHD_NO;
+ }
/* zero-terminate header */
colon[0] = '\0';
colon++; /* advance to value */
@@ -2355,7 +2579,7 @@
* of the given kind
* @return #MHD_YES if the line was processed successfully
*/
-static int
+static enum MHD_Result
process_broken_line (struct MHD_Connection *connection,
char *line,
enum MHD_ValueKind kind)
@@ -2368,64 +2592,69 @@
last = connection->last;
if ( (' ' == line[0]) ||
('\t' == line[0]) )
- {
- /* value was continued on the next line, see
- http://www.jmarshall.com/easy/http/ */
- last_len = strlen (last);
- /* skip whitespace at start of 2nd line */
- tmp = line;
- while ( (' ' == tmp[0]) ||
- ('\t' == tmp[0]) )
- tmp++;
- tmp_len = strlen (tmp);
- /* FIXME: we might be able to do this better (faster!), as most
- likely 'last' and 'line' should already be adjacent in
- memory; however, doing this right gets tricky if we have a
- value continued over multiple lines (in which case we need to
- record how often we have done this so we can check for
- adjacency); also, in the case where these are not adjacent
- (not sure how it can happen!), we would want to allocate from
- the end of the pool, so as to not destroy the read-buffer's
- ability to grow nicely. */
- last = MHD_pool_reallocate (connection->pool,
- last,
- last_len + 1,
- last_len + tmp_len + 1);
- if (NULL == last)
- {
- transmit_error_response (connection,
- MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
- REQUEST_TOO_BIG);
- return MHD_NO;
- }
- memcpy (&last[last_len], tmp, tmp_len + 1);
- connection->last = last;
- return MHD_YES; /* possibly more than 2 lines... */
- }
- EXTRA_CHECK ( (NULL != last) &&
- (NULL != connection->colon) );
- if ((MHD_NO == connection_add_header (connection,
- last,
- connection->colon,
- kind)))
+ {
+ /* value was continued on the next line, see
+ http://www.jmarshall.com/easy/http/ */
+ last_len = strlen (last);
+ /* skip whitespace at start of 2nd line */
+ tmp = line;
+ while ( (' ' == tmp[0]) ||
+ ('\t' == tmp[0]) )
+ tmp++;
+ tmp_len = strlen (tmp);
+ /* FIXME: we might be able to do this better (faster!), as most
+ likely 'last' and 'line' should already be adjacent in
+ memory; however, doing this right gets tricky if we have a
+ value continued over multiple lines (in which case we need to
+ record how often we have done this so we can check for
+ adjacency); also, in the case where these are not adjacent
+ (not sure how it can happen!), we would want to allocate from
+ the end of the pool, so as to not destroy the read-buffer's
+ ability to grow nicely. */
+ last = MHD_pool_reallocate (connection->pool,
+ last,
+ last_len + 1,
+ last_len + tmp_len + 1);
+ if (NULL == last)
{
transmit_error_response (connection,
MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
REQUEST_TOO_BIG);
return MHD_NO;
}
+ memcpy (&last[last_len],
+ tmp,
+ tmp_len + 1);
+ connection->last = last;
+ return MHD_YES; /* possibly more than 2 lines... */
+ }
+ mhd_assert ( (NULL != last) &&
+ (NULL != connection->colon) );
+ if (MHD_NO ==
+ connection_add_header (connection,
+ last,
+ strlen (last),
+ connection->colon,
+ strlen (connection->colon),
+ kind))
+ {
+ transmit_error_response (connection,
+ MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ REQUEST_TOO_BIG);
+ return MHD_NO;
+ }
/* we still have the current line to deal with... */
if (0 != line[0])
+ {
+ if (MHD_NO == process_header_line (connection,
+ line))
{
- if (MHD_NO == process_header_line (connection,
- line))
- {
- transmit_error_response (connection,
- MHD_HTTP_BAD_REQUEST,
- REQUEST_MALFORMED);
- return MHD_NO;
- }
+ transmit_error_response (connection,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ return MHD_NO;
}
+ }
return MHD_YES;
}
@@ -2448,66 +2677,94 @@
parse_cookie_header (connection);
if ( (1 <= connection->daemon->strict_for_client) &&
(NULL != connection->version) &&
- (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1,
- connection->version)) &&
- (NULL ==
- MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_HOST)) )
- {
- /* die, http 1.1 request without host and we are pedantic */
- connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
- connection->read_closed = true;
+ (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
+ connection->version)) &&
+ (MHD_NO ==
+ MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_HOST,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_HOST),
+ NULL,
+ NULL)) )
+ {
+ enum MHD_Result iret;
+
+ /* die, http 1.1 request without host and we are pedantic */
+ connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
+ connection->read_closed = true;
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Received HTTP 1.1 request without `Host' header.\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Received HTTP 1.1 request without `Host' header.\n"));
#endif
- EXTRA_CHECK (NULL == connection->response);
- response =
- MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST),
- REQUEST_LACKS_HOST,
- MHD_RESPMEM_PERSISTENT);
- MHD_queue_response (connection,
- MHD_HTTP_BAD_REQUEST,
- response);
- MHD_destroy_response (response);
+ mhd_assert (NULL == connection->response);
+ response =
+ MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST),
+ REQUEST_LACKS_HOST,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ {
+ /* can't even send a reply, at least close the connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to create response)."));
return;
}
+ iret = MHD_queue_response (connection,
+ MHD_HTTP_BAD_REQUEST,
+ response);
+ MHD_destroy_response (response);
+ if (MHD_NO == iret)
+ {
+ /* can't even send a reply, at least close the connection */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to queue response)."));
+ }
+ return;
+ }
connection->remaining_upload_size = 0;
- enc = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_TRANSFER_ENCODING);
- if (NULL != enc)
- {
- connection->remaining_upload_size = MHD_SIZE_UNKNOWN;
- if (MHD_str_equal_caseless_(enc,
- "chunked"))
- connection->have_chunked_upload = true;
- }
+ if (MHD_NO != MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_TRANSFER_ENCODING),
+ &enc,
+ NULL))
+ {
+ connection->remaining_upload_size = MHD_SIZE_UNKNOWN;
+ if (MHD_str_equal_caseless_ (enc,
+ "chunked"))
+ connection->have_chunked_upload = true;
+ }
else
- {
- clen = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_CONTENT_LENGTH);
- if (NULL != clen)
- {
- end = clen + MHD_str_to_uint64_ (clen,
- &connection->remaining_upload_size);
- if ( (clen == end) ||
- ('\0' != *end) )
- {
- connection->remaining_upload_size = 0;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- "Failed to parse `Content-Length' header. Closing connection.\n");
-#endif
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return;
- }
- }
+ {
+ if (MHD_NO != MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONTENT_LENGTH,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONTENT_LENGTH),
+ &clen,
+ NULL))
+ {
+ end = clen + MHD_str_to_uint64_ (clen,
+ &connection->remaining_upload_size);
+ if ( (clen == end) ||
+ ('\0' != *end) )
+ {
+ connection->remaining_upload_size = 0;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ (
+ "Failed to parse `Content-Length' header. Closing connection.\n"));
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
}
+ }
}
@@ -2524,27 +2781,30 @@
struct MHD_Daemon *daemon = connection->daemon;
if (0 == connection->connection_timeout)
- return; /* Skip update of activity for connections
+ return; /* Skip update of activity for connections
without timeout timer. */
if (connection->suspended)
- return; /* no activity on suspended connections */
+ return; /* no activity on suspended connections */
- connection->last_activity = MHD_monotonic_sec_counter();
+ connection->last_activity = MHD_monotonic_sec_counter ();
if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
return; /* each connection has personal timeout */
if (connection->connection_timeout != daemon->connection_timeout)
return; /* custom timeout, no need to move it in "normal" DLL */
-
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
/* move connection to head of timeout list (by remove + add operation) */
XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
+ daemon->normal_timeout_tail,
+ connection);
XDLL_insert (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
+ daemon->normal_timeout_tail,
+ connection);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
}
@@ -2553,68 +2813,116 @@
* determined that there is data to be read off a socket.
*
* @param connection connection to handle
- * @return always #MHD_YES (we should continue to process the
- * connection)
*/
-int
+void
MHD_connection_handle_read (struct MHD_Connection *connection)
{
+ ssize_t bytes_read;
+
if ( (MHD_CONNECTION_CLOSED == connection->state) ||
(connection->suspended) )
- return MHD_YES;
+ return;
+#ifdef HTTPS_SUPPORT
+ if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+ { /* HTTPS connection. */
+ if (MHD_TLS_CONN_CONNECTED > connection->tls_state)
+ {
+ if (! MHD_run_tls_handshake_ (connection))
+ return;
+ }
+ }
+#endif /* HTTPS_SUPPORT */
+
/* make sure "read" has a reasonable number of bytes
in buffer to use per system call (if possible) */
if (connection->read_buffer_offset + connection->daemon->pool_increment >
connection->read_buffer_size)
- try_grow_read_buffer (connection);
- if (MHD_NO == do_read (connection))
- return MHD_YES;
- MHD_update_last_activity_ (connection);
- while (1)
+ try_grow_read_buffer (connection,
+ (connection->read_buffer_size ==
+ connection->read_buffer_offset));
+
+ if (connection->read_buffer_size == connection->read_buffer_offset)
+ return; /* No space for receiving data. */
+ bytes_read = connection->recv_cls (connection,
+ &connection->read_buffer
+ [connection->read_buffer_offset],
+ connection->read_buffer_size
+ - connection->read_buffer_offset);
+ if (bytes_read < 0)
+ {
+ if (MHD_ERR_AGAIN_ == bytes_read)
+ return; /* No new data to process. */
+ if (MHD_ERR_CONNRESET_ == bytes_read)
{
-#if DEBUG_STATES
+ CONNECTION_CLOSE_ERROR (connection,
+ (MHD_CONNECTION_INIT == connection->state) ?
+ NULL :
+ _ (
+ "Socket disconnected while reading request."));
+ return;
+ }
+
+#ifdef HAVE_MESSAGES
+ if (MHD_CONNECTION_INIT != connection->state)
MHD_DLOG (connection->daemon,
- _("In function %s handling connection at state: %s\n"),
- __FUNCTION__,
- MHD_state_to_string (connection->state));
+ _ ("Connection socket is closed when reading " \
+ "request due to the error: %s\n"),
+ str_conn_error_ (bytes_read));
#endif
- switch (connection->state)
- {
- case MHD_CONNECTION_INIT:
- case MHD_CONNECTION_URL_RECEIVED:
- case MHD_CONNECTION_HEADER_PART_RECEIVED:
- case MHD_CONNECTION_HEADERS_RECEIVED:
- case MHD_CONNECTION_HEADERS_PROCESSED:
- case MHD_CONNECTION_CONTINUE_SENDING:
- case MHD_CONNECTION_CONTINUE_SENT:
- case MHD_CONNECTION_BODY_RECEIVED:
- case MHD_CONNECTION_FOOTER_PART_RECEIVED:
- /* nothing to do but default action */
- if (connection->read_closed)
- {
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_READ_ERROR);
- continue;
- }
- break;
- case MHD_CONNECTION_CLOSED:
- return MHD_YES;
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+
+ if (0 == bytes_read)
+ { /* Remote side closed connection. */
+ connection->read_closed = true;
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_CLIENT_ABORT);
+ return;
+ }
+ connection->read_buffer_offset += bytes_read;
+ MHD_update_last_activity_ (connection);
+#if DEBUG_STATES
+ MHD_DLOG (connection->daemon,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (connection->state));
+#endif
+ switch (connection->state)
+ {
+ case MHD_CONNECTION_INIT:
+ case MHD_CONNECTION_URL_RECEIVED:
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ case MHD_CONNECTION_CONTINUE_SENT:
+ case MHD_CONNECTION_BODY_RECEIVED:
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ /* nothing to do but default action */
+ if (connection->read_closed)
+ {
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_READ_ERROR);
+ }
+ return;
+ case MHD_CONNECTION_CLOSED:
+ return;
#ifdef UPGRADE_SUPPORT
- case MHD_CONNECTION_UPGRADE:
- EXTRA_CHECK (0);
- break;
+ case MHD_CONNECTION_UPGRADE:
+ mhd_assert (0);
+ return;
#endif /* UPGRADE_SUPPORT */
- default:
- /* shrink read buffer to how much is actually used */
- MHD_pool_reallocate (connection->pool,
- connection->read_buffer,
- connection->read_buffer_size + 1,
- connection->read_buffer_offset);
- break;
- }
- break;
- }
- return MHD_YES;
+ default:
+ /* shrink read buffer to how much is actually used */
+ MHD_pool_reallocate (connection->pool,
+ connection->read_buffer,
+ connection->read_buffer_size + 1,
+ connection->read_buffer_offset);
+ break;
+ }
+ return;
}
@@ -2623,192 +2931,328 @@
* been determined that the socket can be written to.
*
* @param connection connection to handle
- * @return always #MHD_YES (we should continue to process the
- * connection)
*/
-int
+void
MHD_connection_handle_write (struct MHD_Connection *connection)
{
struct MHD_Response *response;
ssize_t ret;
if (connection->suspended)
- return MHD_YES;
+ return;
- while (1)
+#ifdef HTTPS_SUPPORT
+ if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+ { /* HTTPS connection. */
+ if (MHD_TLS_CONN_CONNECTED > connection->tls_state)
{
+ if (! MHD_run_tls_handshake_ (connection))
+ return;
+ }
+ }
+#endif /* HTTPS_SUPPORT */
+
#if DEBUG_STATES
+ MHD_DLOG (connection->daemon,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (connection->state));
+#endif
+ switch (connection->state)
+ {
+ case MHD_CONNECTION_INIT:
+ case MHD_CONNECTION_URL_RECEIVED:
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ mhd_assert (0);
+ return;
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ return;
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ ret = MHD_send_data_ (connection,
+ &HTTP_100_CONTINUE
+ [connection->continue_message_write_offset],
+ MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)
+ - connection->continue_message_write_offset,
+ true);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
MHD_DLOG (connection->daemon,
- _("In function %s handling connection at state: %s\n"),
- __FUNCTION__,
- MHD_state_to_string (connection->state));
+ _ ("Failed to send data in request for %s.\n"),
+ connection->url);
#endif
- switch (connection->state)
- {
- case MHD_CONNECTION_INIT:
- case MHD_CONNECTION_URL_RECEIVED:
- case MHD_CONNECTION_HEADER_PART_RECEIVED:
- case MHD_CONNECTION_HEADERS_RECEIVED:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_HEADERS_PROCESSED:
- break;
- case MHD_CONNECTION_CONTINUE_SENDING:
- ret = connection->send_cls (connection,
- &HTTP_100_CONTINUE
- [connection->continue_message_write_offset],
- MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) -
- connection->continue_message_write_offset);
- if (ret < 0)
- {
- const int err = MHD_socket_get_error_ ();
-
- if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
- MHD_SCKT_ERR_IS_EAGAIN_ (err))
- break;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to send data in request for %s: %s\n"),
- connection->url,
- MHD_socket_strerr_ (err));
-#endif
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return MHD_YES;
- }
-#if DEBUG_SEND_DATA
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+#if _MHD_DEBUG_SEND_DATA
+ fprintf (stderr,
+ _ ("Sent 100 continue response: `%.*s'\n"),
+ (int) ret,
+ &HTTP_100_CONTINUE[connection->continue_message_write_offset]);
+#endif
+ connection->continue_message_write_offset += ret;
+ MHD_update_last_activity_ (connection);
+ return;
+ case MHD_CONNECTION_CONTINUE_SENT:
+ case MHD_CONNECTION_BODY_RECEIVED:
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ mhd_assert (0);
+ return;
+ case MHD_CONNECTION_HEADERS_SENDING:
+ {
+ struct MHD_Response *const resp = connection->response;
+ const size_t wb_ready = connection->write_buffer_append_offset
+ - connection->write_buffer_send_offset;
+ mhd_assert (connection->write_buffer_append_offset >= \
+ connection->write_buffer_send_offset);
+ mhd_assert (NULL != resp);
+ mhd_assert ( (0 == resp->data_size) || \
+ (0 == resp->data_start) || \
+ (NULL != resp->crc) );
+ mhd_assert ( (0 == connection->response_write_position) || \
+ (resp->total_size ==
+ connection->response_write_position) || \
+ (MHD_SIZE_UNKNOWN ==
+ connection->response_write_position) );
+
+ if ( (NULL == resp->crc) &&
+ (NULL == resp->data_iov) &&
+ (0 == connection->response_write_position) )
+ {
+ mhd_assert (resp->total_size >= resp->data_size);
+ /* Send response headers alongside the response body, if the body
+ * data is available. */
+ ret = MHD_send_hdr_and_body_ (connection,
+ &connection->write_buffer
+ [connection->write_buffer_send_offset],
+ wb_ready,
+ false,
+ resp->data,
+ resp->data_size,
+ (resp->total_size == resp->data_size));
+ }
+ else
+ {
+ /* This is response for HEAD request or reply body is not allowed
+ * for any other reason or reply body is dynamically generated. */
+ /* Do not send the body data even if it's available. */
+ ret = MHD_send_hdr_and_body_ (connection,
+ &connection->write_buffer
+ [connection->write_buffer_send_offset],
+ wb_ready,
+ false,
+ NULL,
+ 0,
+ ((0 == resp->total_size) ||
+ (resp->total_size ==
+ connection->response_write_position) ||
+ (MHD_SIZE_UNKNOWN ==
+ connection->response_write_position)));
+ }
+
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to send the response headers for the " \
+ "request for `%s'. Error: %s\n"),
+ connection->url,
+ str_conn_error_ (ret));
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+ /* 'ret' is not negative, it's safe to cast it to 'size_t'. */
+ if (((size_t) ret) > wb_ready)
+ {
+ /* The complete header and some response data have been sent,
+ * update both offsets. */
+ mhd_assert (0 == connection->response_write_position);
+ mhd_assert (! connection->have_chunked_upload);
+ connection->write_buffer_send_offset += wb_ready;
+ connection->response_write_position = ret - wb_ready;
+ }
+ else
+ connection->write_buffer_send_offset += ret;
+ MHD_update_last_activity_ (connection);
+ if (MHD_CONNECTION_HEADERS_SENDING != connection->state)
+ return;
+ check_write_done (connection,
+ MHD_CONNECTION_HEADERS_SENT);
+ return;
+ }
+ case MHD_CONNECTION_HEADERS_SENT:
+ return;
+ case MHD_CONNECTION_NORMAL_BODY_READY:
+ response = connection->response;
+ if (connection->response_write_position <
+ connection->response->total_size)
+ {
+ uint64_t data_write_offset;
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != response->crc)
+ MHD_mutex_lock_chk_ (&response->mutex);
+#endif
+ if (MHD_NO == try_ready_normal_body (connection))
+ {
+ /* mutex was already unlocked by try_ready_normal_body */
+ return;
+ }
+#if defined(_MHD_HAVE_SENDFILE)
+ if (MHD_resp_sender_sendfile == connection->resp_sender)
+ {
+ mhd_assert (NULL == response->data_iov);
+ ret = MHD_send_sendfile_ (connection);
+ }
+ else /* combined with the next 'if' */
+#endif /* _MHD_HAVE_SENDFILE */
+ if (NULL != response->data_iov)
+ {
+ ret = MHD_send_iovec_ (connection,
+ &connection->resp_iov,
+ true);
+ }
+ else
+ {
+ data_write_offset = connection->response_write_position
+ - response->data_start;
+ if (data_write_offset > (uint64_t) SIZE_MAX)
+ MHD_PANIC (_ ("Data offset exceeds limit.\n"));
+ ret = MHD_send_data_ (connection,
+ &response->data
+ [(size_t) data_write_offset],
+ response->data_size
+ - (size_t) data_write_offset,
+ true);
+#if _MHD_DEBUG_SEND_DATA
+ if (ret > 0)
fprintf (stderr,
- _("Sent 100 continue response: `%.*s'\n"),
+ _ ("Sent %d-byte DATA response: `%.*s'\n"),
+ (int) ret,
(int) ret,
- &HTTP_100_CONTINUE[connection->continue_message_write_offset]);
+ &response->data[connection->response_write_position
+ - response->data_start]);
#endif
- connection->continue_message_write_offset += ret;
- MHD_update_last_activity_ (connection);
- break;
- case MHD_CONNECTION_CONTINUE_SENT:
- case MHD_CONNECTION_BODY_RECEIVED:
- case MHD_CONNECTION_FOOTER_PART_RECEIVED:
- case MHD_CONNECTION_FOOTERS_RECEIVED:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_HEADERS_SENDING:
- if (MHD_NO != do_write (connection))
- MHD_update_last_activity_ (connection);
- if (MHD_CONNECTION_HEADERS_SENDING != connection->state)
- break;
- check_write_done (connection,
- MHD_CONNECTION_HEADERS_SENT);
- break;
- case MHD_CONNECTION_HEADERS_SENT:
- break;
- case MHD_CONNECTION_NORMAL_BODY_READY:
- response = connection->response;
- if (connection->response_write_position <
- connection->response->total_size)
- {
- int err;
- uint64_t data_write_offset;
-
- if (NULL != response->crc)
- MHD_mutex_lock_chk_ (&response->mutex);
- if (MHD_YES != try_ready_normal_body (connection))
- {
- /* mutex was already unlocked by try_ready_normal_body */
- break;
- }
- data_write_offset = connection->response_write_position
- - response->data_start;
- if (data_write_offset > (uint64_t)SIZE_MAX)
- MHD_PANIC (_("Data offset exceeds limit"));
- ret = connection->send_cls (connection,
- &response->data
- [(size_t)data_write_offset],
- response->data_size -
- (size_t)data_write_offset);
-#if DEBUG_SEND_DATA
- if (ret > 0)
- fprintf (stderr,
- _("Sent %d-byte DATA response: `%.*s'\n"),
- (int) ret,
- (int) ret,
- &response->data[connection->response_write_position -
- response->data_start]);
-#endif
- if (NULL != response->crc)
- MHD_mutex_unlock_chk_ (&response->mutex);
- if (ret < 0)
- {
- err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
- MHD_SCKT_ERR_IS_EAGAIN_ (err))
- return MHD_YES;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to send data in request for `%s': %s\n"),
- connection->url,
- MHD_socket_strerr_ (err));
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != response->crc)
+ MHD_mutex_unlock_chk_ (&response->mutex);
#endif
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- return MHD_YES;
- }
- connection->response_write_position += ret;
- MHD_update_last_activity_ (connection);
- }
- if (connection->response_write_position ==
- connection->response->total_size)
- connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */
- break;
- case MHD_CONNECTION_NORMAL_BODY_UNREADY:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_CHUNKED_BODY_READY:
- if (MHD_NO != do_write (connection))
- MHD_update_last_activity_ (connection);
- if (MHD_CONNECTION_CHUNKED_BODY_READY != connection->state)
- break;
- check_write_done (connection,
- (connection->response->total_size ==
- connection->response_write_position) ?
- MHD_CONNECTION_BODY_SENT :
- MHD_CONNECTION_CHUNKED_BODY_UNREADY);
- break;
- case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
- case MHD_CONNECTION_BODY_SENT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_FOOTERS_SENDING:
- if (MHD_NO != do_write (connection))
- MHD_update_last_activity_ (connection);
- if (MHD_CONNECTION_FOOTERS_SENDING != connection->state)
- break;
- check_write_done (connection,
- MHD_CONNECTION_FOOTERS_SENT);
- break;
- case MHD_CONNECTION_FOOTERS_SENT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_CLOSED:
- return MHD_YES;
- case MHD_TLS_CONNECTION_INIT:
- EXTRA_CHECK (0);
- break;
- case MHD_CONNECTION_IN_CLEANUP:
- EXTRA_CHECK (0);
- break;
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to send the response body for the " \
+ "request for `%s'. Error: %s\n"),
+ connection->url,
+ str_conn_error_ (ret));
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+ connection->response_write_position += ret;
+ MHD_update_last_activity_ (connection);
+ }
+ if (connection->response_write_position ==
+ connection->response->total_size)
+ connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */
+ return;
+ case MHD_CONNECTION_NORMAL_BODY_UNREADY:
+ mhd_assert (0);
+ return;
+ case MHD_CONNECTION_CHUNKED_BODY_READY:
+ ret = MHD_send_data_ (connection,
+ &connection->write_buffer
+ [connection->write_buffer_send_offset],
+ connection->write_buffer_append_offset
+ - connection->write_buffer_send_offset,
+ true);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to send the chunked response body for the " \
+ "request for `%s'. Error: %s\n"),
+ connection->url,
+ str_conn_error_ (ret));
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+ connection->write_buffer_send_offset += ret;
+ MHD_update_last_activity_ (connection);
+ if (MHD_CONNECTION_CHUNKED_BODY_READY != connection->state)
+ return;
+ check_write_done (connection,
+ (connection->response->total_size ==
+ connection->response_write_position) ?
+ MHD_CONNECTION_BODY_SENT :
+ MHD_CONNECTION_CHUNKED_BODY_UNREADY);
+ return;
+ case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
+ case MHD_CONNECTION_BODY_SENT:
+ mhd_assert (0);
+ return;
+ case MHD_CONNECTION_FOOTERS_SENDING:
+ ret = MHD_send_data_ (connection,
+ &connection->write_buffer
+ [connection->write_buffer_send_offset],
+ connection->write_buffer_append_offset
+ - connection->write_buffer_send_offset,
+ true);
+ if (ret < 0)
+ {
+ if (MHD_ERR_AGAIN_ == ret)
+ return;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to send the footers for the " \
+ "request for `%s'. Error: %s\n"),
+ connection->url,
+ str_conn_error_ (ret));
+#endif
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ return;
+ }
+ connection->write_buffer_send_offset += ret;
+ MHD_update_last_activity_ (connection);
+ if (MHD_CONNECTION_FOOTERS_SENDING != connection->state)
+ return;
+ check_write_done (connection,
+ MHD_CONNECTION_FOOTERS_SENT);
+ return;
+ case MHD_CONNECTION_FOOTERS_SENT:
+ mhd_assert (0);
+ return;
+ case MHD_CONNECTION_CLOSED:
+ return;
#ifdef UPGRADE_SUPPORT
- case MHD_CONNECTION_UPGRADE:
- EXTRA_CHECK (0);
- break;
+ case MHD_CONNECTION_UPGRADE:
+ mhd_assert (0);
+ return;
#endif /* UPGRADE_SUPPORT */
- default:
- EXTRA_CHECK (0);
- CONNECTION_CLOSE_ERROR (connection,
- _("Internal error\n"));
- return MHD_YES;
- }
- break;
- }
- return MHD_YES;
+ default:
+ mhd_assert (0);
+ CONNECTION_CLOSE_ERROR (connection,
+ _ ("Internal error.\n"));
+ break;
+ }
+ return;
}
@@ -2824,60 +3268,69 @@
cleanup_connection (struct MHD_Connection *connection)
{
struct MHD_Daemon *daemon = connection->daemon;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (connection->pid) );
+#endif /* MHD_USE_THREADS */
if (connection->in_cleanup)
return; /* Prevent double cleanup. */
connection->in_cleanup = true;
if (NULL != connection->response)
- {
- MHD_destroy_response (connection->response);
- connection->response = NULL;
- }
+ {
+ MHD_destroy_response (connection->response);
+ connection->response = NULL;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if (connection->suspended)
- {
- DLL_remove (daemon->suspended_connections_head,
- daemon->suspended_connections_tail,
- connection);
- connection->suspended = false;
- }
+ {
+ DLL_remove (daemon->suspended_connections_head,
+ daemon->suspended_connections_tail,
+ connection);
+ connection->suspended = false;
+ }
else
+ {
+ if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
{
- if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
- if (connection->connection_timeout == daemon->connection_timeout)
- XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
- else
- XDLL_remove (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- connection);
- }
- DLL_remove (daemon->connections_head,
- daemon->connections_tail,
- connection);
- }
+ if (connection->connection_timeout == daemon->connection_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ DLL_remove (daemon->connections_head,
+ daemon->connections_tail,
+ connection);
+ }
DLL_insert (daemon->cleanup_head,
- daemon->cleanup_tail,
- connection);
+ daemon->cleanup_tail,
+ connection);
connection->resuming = false;
connection->in_idle = false;
- MHD_mutex_unlock_chk_(&daemon->cleanup_connection_mutex);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+ {
+ /* if we were at the connection limit before and are in
+ thread-per-connection mode, signal the main thread
+ to resume accepting connections */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc, "c")) )
{
- /* if we were at the connection limit before and are in
- thread-per-connection mode, signal the main thread
- to resume accepting connections */
- if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
- (! MHD_itc_activate_ (daemon->itc, "c")) )
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to signal end of connection via inter-thread communication channel"));
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to signal end of connection via inter-thread communication channel.\n"));
#endif
- }
}
+ }
}
@@ -2891,490 +3344,488 @@
* @return #MHD_YES if we should continue to process the
* connection (not dead yet), #MHD_NO if it died
*/
-int
+enum MHD_Result
MHD_connection_handle_idle (struct MHD_Connection *connection)
{
struct MHD_Daemon *daemon = connection->daemon;
char *line;
size_t line_len;
- int ret;
+ enum MHD_Result ret;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (connection->pid) );
+#endif /* MHD_USE_THREADS */
connection->in_idle = true;
while (! connection->suspended)
- {
+ {
+#ifdef HTTPS_SUPPORT
+ if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
+ { /* HTTPS connection. */
+ if ((MHD_TLS_CONN_INIT <= connection->tls_state) &&
+ (MHD_TLS_CONN_CONNECTED > connection->tls_state))
+ break;
+ }
+#endif /* HTTPS_SUPPORT */
#if DEBUG_STATES
- MHD_DLOG (daemon,
- _("In function %s handling connection at state: %s\n"),
- __FUNCTION__,
- MHD_state_to_string (connection->state));
+ MHD_DLOG (daemon,
+ _ ("In function %s handling connection at state: %s\n"),
+ __FUNCTION__,
+ MHD_state_to_string (connection->state));
#endif
- switch (connection->state)
+ switch (connection->state)
+ {
+ case MHD_CONNECTION_INIT:
+ line = get_next_header_line (connection,
+ &line_len);
+ /* Check for empty string, as we might want
+ to tolerate 'spurious' empty lines; also
+ NULL means we didn't get a full line yet;
+ line is not 0-terminated here. */
+ if ( (NULL == line) ||
+ (0 == line[0]) )
+ {
+ if (MHD_CONNECTION_INIT != connection->state)
+ continue;
+ if (connection->read_closed)
{
- case MHD_CONNECTION_INIT:
- line = get_next_header_line (connection,
- &line_len);
- /* Check for empty string, as we might want
- to tolerate 'spurious' empty lines; also
- NULL means we didn't get a full line yet;
- line is not 0-terminated here. */
- if ( (NULL == line) ||
- (0 == line[0]) )
- {
- if (MHD_CONNECTION_INIT != connection->state)
- continue;
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- break;
- }
- if (MHD_NO == parse_initial_message_line (connection,
- line,
- line_len))
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- else
- connection->state = MHD_CONNECTION_URL_RECEIVED;
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
continue;
- case MHD_CONNECTION_URL_RECEIVED:
- line = get_next_header_line (connection,
- NULL);
- if (NULL == line)
- {
- if (MHD_CONNECTION_URL_RECEIVED != connection->state)
- continue;
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- break;
- }
- if (0 == line[0])
- {
- connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
- connection->header_size = (size_t) (line - connection->read_buffer);
- continue;
- }
- if (MHD_NO == process_header_line (connection,
- line))
- {
- transmit_error_response (connection,
- MHD_HTTP_BAD_REQUEST,
- REQUEST_MALFORMED);
- break;
- }
- connection->state = MHD_CONNECTION_HEADER_PART_RECEIVED;
+ }
+ break;
+ }
+ if (MHD_NO == parse_initial_message_line (connection,
+ line,
+ line_len))
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ else
+ connection->state = MHD_CONNECTION_URL_RECEIVED;
+ continue;
+ case MHD_CONNECTION_URL_RECEIVED:
+ line = get_next_header_line (connection,
+ NULL);
+ if (NULL == line)
+ {
+ if (MHD_CONNECTION_URL_RECEIVED != connection->state)
continue;
- case MHD_CONNECTION_HEADER_PART_RECEIVED:
- line = get_next_header_line (connection,
- NULL);
- if (NULL == line)
- {
- if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
- continue;
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- break;
- }
- if (MHD_NO ==
- process_broken_line (connection,
- line,
- MHD_HEADER_KIND))
- continue;
- if (0 == line[0])
- {
- connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
- connection->header_size = (size_t) (line - connection->read_buffer);
- continue;
- }
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
continue;
- case MHD_CONNECTION_HEADERS_RECEIVED:
- parse_connection_headers (connection);
- if (MHD_CONNECTION_CLOSED == connection->state)
- continue;
- connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
- if (connection->suspended)
- break;
+ }
+ break;
+ }
+ if (0 == line[0])
+ {
+ connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
+ connection->header_size = (size_t) (line - connection->read_buffer);
+ continue;
+ }
+ if (MHD_NO == process_header_line (connection,
+ line))
+ {
+ transmit_error_response (connection,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ break;
+ }
+ connection->state = MHD_CONNECTION_HEADER_PART_RECEIVED;
+ continue;
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ line = get_next_header_line (connection,
+ NULL);
+ if (NULL == line)
+ {
+ if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
continue;
- case MHD_CONNECTION_HEADERS_PROCESSED:
- call_connection_handler (connection); /* first call */
- if (MHD_CONNECTION_CLOSED == connection->state)
- continue;
- if (need_100_continue (connection))
- {
- connection->state = MHD_CONNECTION_CONTINUE_SENDING;
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_extra_buffering (connection);
- else
- socket_start_no_buffering (connection);
-
- break;
- }
- if ( (NULL != connection->response) &&
- ( (MHD_str_equal_caseless_ (connection->method,
- MHD_HTTP_METHOD_POST)) ||
- (MHD_str_equal_caseless_ (connection->method,
- MHD_HTTP_METHOD_PUT))) )
- {
- /* we refused (no upload allowed!) */
- connection->remaining_upload_size = 0;
- /* force close, in case client still tries to upload... */
- connection->read_closed = true;
- }
- connection->state = (0 == connection->remaining_upload_size)
- ? MHD_CONNECTION_FOOTERS_RECEIVED : MHD_CONNECTION_CONTINUE_SENT;
- if (connection->suspended)
- break;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
continue;
- case MHD_CONNECTION_CONTINUE_SENDING:
- if (connection->continue_message_write_offset ==
- MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE))
- {
- connection->state = MHD_CONNECTION_CONTINUE_SENT;
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_no_buffering_flush (connection);
- else
- socket_start_normal_buffering (connection);
-
- continue;
- }
- break;
- case MHD_CONNECTION_CONTINUE_SENT:
- if (0 != connection->read_buffer_offset)
- {
- process_request_body (connection); /* loop call */
- if (MHD_CONNECTION_CLOSED == connection->state)
- continue;
- }
- if ( (0 == connection->remaining_upload_size) ||
- ( (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) &&
- (0 == connection->read_buffer_offset) &&
- (connection->read_closed) ) )
- {
- if ( (connection->have_chunked_upload) &&
- (! connection->read_closed) )
- connection->state = MHD_CONNECTION_BODY_RECEIVED;
- else
- connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
- if (connection->suspended)
- break;
- continue;
- }
+ }
+ break;
+ }
+ if (MHD_NO ==
+ process_broken_line (connection,
+ line,
+ MHD_HEADER_KIND))
+ continue;
+ if (0 == line[0])
+ {
+ connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
+ connection->header_size = (size_t) (line - connection->read_buffer);
+ continue;
+ }
+ continue;
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ parse_connection_headers (connection);
+ if (MHD_CONNECTION_CLOSED == connection->state)
+ continue;
+ connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
+ if (connection->suspended)
+ break;
+ continue;
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ call_connection_handler (connection); /* first call */
+ if (MHD_CONNECTION_CLOSED == connection->state)
+ continue;
+ if (connection->suspended)
+ continue;
+ if ( (NULL == connection->response) &&
+ (need_100_continue (connection)) )
+ {
+ connection->state = MHD_CONNECTION_CONTINUE_SENDING;
+ break;
+ }
+ if ( (NULL != connection->response) &&
+ (0 != connection->remaining_upload_size) )
+ {
+ /* we refused (no upload allowed!) */
+ connection->remaining_upload_size = 0;
+ /* force close, in case client still tries to upload... */
+ connection->read_closed = true;
+ }
+ connection->state = (0 == connection->remaining_upload_size)
+ ? MHD_CONNECTION_FOOTERS_RECEIVED
+ : MHD_CONNECTION_CONTINUE_SENT;
+ if (connection->suspended)
+ break;
+ continue;
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ if (connection->continue_message_write_offset ==
+ MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE))
+ {
+ connection->state = MHD_CONNECTION_CONTINUE_SENT;
+ continue;
+ }
+ break;
+ case MHD_CONNECTION_CONTINUE_SENT:
+ if (0 != connection->read_buffer_offset)
+ {
+ process_request_body (connection); /* loop call */
+ if (MHD_CONNECTION_CLOSED == connection->state)
+ continue;
+ }
+ if ( (0 == connection->remaining_upload_size) ||
+ ( (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) &&
+ (0 == connection->read_buffer_offset) &&
+ (connection->read_closed) ) )
+ {
+ if ( (connection->have_chunked_upload) &&
+ (! connection->read_closed) )
+ connection->state = MHD_CONNECTION_BODY_RECEIVED;
+ else
+ connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
+ if (connection->suspended)
break;
- case MHD_CONNECTION_BODY_RECEIVED:
- line = get_next_header_line (connection,
- NULL);
- if (NULL == line)
- {
- if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
- continue;
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- break;
- }
- if (0 == line[0])
- {
- connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
- if (connection->suspended)
- break;
- continue;
- }
- if (MHD_NO == process_header_line (connection,
- line))
- {
- transmit_error_response (connection,
- MHD_HTTP_BAD_REQUEST,
- REQUEST_MALFORMED);
- break;
- }
- connection->state = MHD_CONNECTION_FOOTER_PART_RECEIVED;
+ continue;
+ }
+ break;
+ case MHD_CONNECTION_BODY_RECEIVED:
+ line = get_next_header_line (connection,
+ NULL);
+ if (NULL == line)
+ {
+ if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
continue;
- case MHD_CONNECTION_FOOTER_PART_RECEIVED:
- line = get_next_header_line (connection,
- NULL);
- if (NULL == line)
- {
- if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
- continue;
- if (connection->read_closed)
- {
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- break;
- }
- if (MHD_NO ==
- process_broken_line (connection,
- line,
- MHD_FOOTER_KIND))
- continue;
- if (0 == line[0])
- {
- connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
- if (connection->suspended)
- break;
- continue;
- }
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
continue;
- case MHD_CONNECTION_FOOTERS_RECEIVED:
- call_connection_handler (connection); /* "final" call */
- if (connection->state == MHD_CONNECTION_CLOSED)
- continue;
- if (NULL == connection->response)
- break; /* try again next time */
- if (MHD_NO == build_header_response (connection))
- {
- /* oops - close! */
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (failed to create response header)\n"));
- continue;
- }
- connection->state = MHD_CONNECTION_HEADERS_SENDING;
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_extra_buffering (connection);
- else
- socket_start_no_buffering (connection);
-
- break;
- case MHD_CONNECTION_HEADERS_SENDING:
- /* no default action */
+ }
+ break;
+ }
+ if (0 == line[0])
+ {
+ connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
+ if (connection->suspended)
break;
- case MHD_CONNECTION_HEADERS_SENT:
- /* Some clients may take some actions right after header receive */
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_no_buffering_flush (connection);
-
-#ifdef UPGRADE_SUPPORT
- if (NULL != connection->response->upgrade_handler)
- {
- socket_start_normal_buffering (connection);
- connection->state = MHD_CONNECTION_UPGRADE;
- /* This connection is "upgraded". Pass socket to application. */
- if (MHD_YES !=
- MHD_response_execute_upgrade_ (connection->response,
- connection))
- {
- /* upgrade failed, fail hard */
- CONNECTION_CLOSE_ERROR (connection,
- NULL);
- continue;
- }
- /* Response is not required anymore for this connection. */
- if (NULL != connection->response)
- {
- struct MHD_Response * const resp = connection->response;
- connection->response = NULL;
- MHD_destroy_response (resp);
- }
- continue;
- }
-#endif /* UPGRADE_SUPPORT */
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_extra_buffering (connection);
- else
- socket_start_normal_buffering (connection);
-
- if (connection->have_chunked_upload)
- connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
- else
- connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
+ continue;
+ }
+ if (MHD_NO == process_header_line (connection,
+ line))
+ {
+ transmit_error_response (connection,
+ MHD_HTTP_BAD_REQUEST,
+ REQUEST_MALFORMED);
+ break;
+ }
+ connection->state = MHD_CONNECTION_FOOTER_PART_RECEIVED;
+ continue;
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ line = get_next_header_line (connection,
+ NULL);
+ if (NULL == line)
+ {
+ if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
continue;
- case MHD_CONNECTION_NORMAL_BODY_READY:
- /* nothing to do here */
- break;
- case MHD_CONNECTION_NORMAL_BODY_UNREADY:
- if (NULL != connection->response->crc)
- MHD_mutex_lock_chk_ (&connection->response->mutex);
- if (0 == connection->response->total_size)
- {
- if (NULL != connection->response->crc)
- MHD_mutex_unlock_chk_ (&connection->response->mutex);
- connection->state = MHD_CONNECTION_BODY_SENT;
- continue;
- }
- if (MHD_YES == try_ready_normal_body (connection))
- {
- if (NULL != connection->response->crc)
- MHD_mutex_unlock_chk_ (&connection->response->mutex);
- connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
- /* Buffering for flushable socket was already enabled*/
- if (MHD_NO == socket_flush_possible (connection))
- socket_start_no_buffering (connection);
- break;
- }
- /* mutex was already unlocked by "try_ready_normal_body */
- /* not ready, no socket action */
- break;
- case MHD_CONNECTION_CHUNKED_BODY_READY:
- /* nothing to do here */
- break;
- case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
- if (NULL != connection->response->crc)
- MHD_mutex_lock_chk_ (&connection->response->mutex);
- if ( (0 == connection->response->total_size) ||
- (connection->response_write_position ==
- connection->response->total_size) )
- {
- if (NULL != connection->response->crc)
- MHD_mutex_unlock_chk_ (&connection->response->mutex);
- connection->state = MHD_CONNECTION_BODY_SENT;
- continue;
- }
- if (MHD_YES == try_ready_chunked_body (connection))
- {
- if (NULL != connection->response->crc)
- MHD_mutex_unlock_chk_ (&connection->response->mutex);
- connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
- /* Buffering for flushable socket was already enabled */
- if (MHD_NO == socket_flush_possible (connection))
- socket_start_no_buffering (connection);
- continue;
- }
- if (NULL != connection->response->crc)
- MHD_mutex_unlock_chk_ (&connection->response->mutex);
- break;
- case MHD_CONNECTION_BODY_SENT:
- if (MHD_NO == build_header_response (connection))
- {
- /* oops - close! */
- CONNECTION_CLOSE_ERROR (connection,
- _("Closing connection (failed to create response header)\n"));
- continue;
- }
- if ( (! connection->have_chunked_upload) ||
- (connection->write_buffer_send_offset ==
- connection->write_buffer_append_offset) )
- connection->state = MHD_CONNECTION_FOOTERS_SENT;
- else
- connection->state = MHD_CONNECTION_FOOTERS_SENDING;
+ if (connection->read_closed)
+ {
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
continue;
- case MHD_CONNECTION_FOOTERS_SENDING:
- /* no default action */
+ }
+ break;
+ }
+ if (MHD_NO ==
+ process_broken_line (connection,
+ line,
+ MHD_FOOTER_KIND))
+ continue;
+ if (0 == line[0])
+ {
+ connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
+ if (connection->suspended)
break;
- case MHD_CONNECTION_FOOTERS_SENT:
- if (MHD_HTTP_PROCESSING == connection->responseCode)
- {
- /* After this type of response, we allow sending another! */
- connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
- MHD_destroy_response (connection->response);
- connection->response = NULL;
- /* FIXME: maybe partially reset memory pool? */
- continue;
- }
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_no_buffering_flush (connection);
- else
- socket_start_normal_buffering (connection);
+ continue;
+ }
+ continue;
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ call_connection_handler (connection); /* "final" call */
+ if (connection->state == MHD_CONNECTION_CLOSED)
+ continue;
+ if (NULL == connection->response)
+ break; /* try again next time */
+ if (MHD_NO == build_header_response (connection))
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to create response header).\n"));
+ continue;
+ }
+ connection->state = MHD_CONNECTION_HEADERS_SENDING;
+ break;
+ case MHD_CONNECTION_HEADERS_SENDING:
+ /* no default action */
+ break;
+ case MHD_CONNECTION_HEADERS_SENT:
+ /* Some clients may take some actions right after header receive */
+#ifdef UPGRADE_SUPPORT
+ if (NULL != connection->response->upgrade_handler)
+ {
+ connection->state = MHD_CONNECTION_UPGRADE;
+ /* This connection is "upgraded". Pass socket to application. */
+ if (MHD_NO ==
+ MHD_response_execute_upgrade_ (connection->response,
+ connection))
+ {
+ /* upgrade failed, fail hard */
+ CONNECTION_CLOSE_ERROR (connection,
+ NULL);
+ continue;
+ }
+ /* Response is not required anymore for this connection. */
+ {
+ struct MHD_Response *const resp = connection->response;
- MHD_destroy_response (connection->response);
connection->response = NULL;
- if ( (NULL != daemon->notify_completed) &&
- (connection->client_aware) )
- {
- connection->client_aware = false;
- daemon->notify_completed (daemon->notify_completed_cls,
- connection,
- &connection->client_context,
- MHD_REQUEST_TERMINATED_COMPLETED_OK);
- }
- if ( (MHD_CONN_USE_KEEPALIVE != connection->keepalive) ||
- (connection->read_closed) )
- {
- /* have to close for some reason */
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_COMPLETED_OK);
- MHD_pool_destroy (connection->pool);
- connection->pool = NULL;
- connection->read_buffer = NULL;
- connection->read_buffer_size = 0;
- connection->read_buffer_offset = 0;
- }
- else
- {
- /* can try to keep-alive */
- if (MHD_NO != socket_flush_possible (connection))
- socket_start_normal_buffering (connection);
- connection->version = NULL;
- connection->state = MHD_CONNECTION_INIT;
- connection->last = NULL;
- connection->colon = NULL;
- connection->header_size = 0;
- connection->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
- /* Reset the read buffer to the starting size,
- preserving the bytes we have already read. */
- connection->read_buffer
- = MHD_pool_reset (connection->pool,
- connection->read_buffer,
- connection->read_buffer_offset,
- connection->daemon->pool_size / 2);
- connection->read_buffer_size
- = connection->daemon->pool_size / 2;
- }
- connection->client_aware = false;
- connection->client_context = NULL;
- connection->continue_message_write_offset = 0;
- connection->responseCode = 0;
- connection->headers_received = NULL;
- connection->headers_received_tail = NULL;
- connection->response_write_position = 0;
- connection->have_chunked_upload = false;
- connection->current_chunk_size = 0;
- connection->current_chunk_offset = 0;
- connection->method = NULL;
- connection->url = NULL;
- connection->write_buffer = NULL;
- connection->write_buffer_size = 0;
- connection->write_buffer_send_offset = 0;
- connection->write_buffer_append_offset = 0;
- continue;
- case MHD_CONNECTION_CLOSED:
- cleanup_connection (connection);
- return MHD_NO;
+ MHD_destroy_response (resp);
+ }
+ continue;
+ }
+#endif /* UPGRADE_SUPPORT */
+
+ if (connection->have_chunked_upload)
+ connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
+ else
+ connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
+ continue;
+ case MHD_CONNECTION_NORMAL_BODY_READY:
+ /* nothing to do here */
+ break;
+ case MHD_CONNECTION_NORMAL_BODY_UNREADY:
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_lock_chk_ (&connection->response->mutex);
+#endif
+ if (0 == connection->response->total_size)
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_unlock_chk_ (&connection->response->mutex);
+#endif
+ connection->state = MHD_CONNECTION_BODY_SENT;
+ continue;
+ }
+ if (MHD_NO != try_ready_normal_body (connection))
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_unlock_chk_ (&connection->response->mutex);
+#endif
+ connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
+ /* Buffering for flushable socket was already enabled*/
+
+ break;
+ }
+ /* mutex was already unlocked by "try_ready_normal_body */
+ /* not ready, no socket action */
+ break;
+ case MHD_CONNECTION_CHUNKED_BODY_READY:
+ /* nothing to do here */
+ break;
+ case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_lock_chk_ (&connection->response->mutex);
+#endif
+ if ( (0 == connection->response->total_size) ||
+ (connection->response_write_position ==
+ connection->response->total_size) )
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_unlock_chk_ (&connection->response->mutex);
+#endif
+ connection->state = MHD_CONNECTION_BODY_SENT;
+ continue;
+ }
+ if (MHD_NO != try_ready_chunked_body (connection))
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != connection->response->crc)
+ MHD_mutex_unlock_chk_ (&connection->response->mutex);
+#endif
+ connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
+ /* Buffering for flushable socket was already enabled */
+
+ continue;
+ }
+ /* mutex was already unlocked by try_ready_chunked_body */
+ break;
+ case MHD_CONNECTION_BODY_SENT:
+ if (MHD_NO == build_header_response (connection))
+ {
+ /* oops - close! */
+ CONNECTION_CLOSE_ERROR (connection,
+ _ (
+ "Closing connection (failed to create response header)."));
+ continue;
+ }
+ if ( (! connection->have_chunked_upload) ||
+ (connection->write_buffer_send_offset ==
+ connection->write_buffer_append_offset) )
+ connection->state = MHD_CONNECTION_FOOTERS_SENT;
+ else
+ connection->state = MHD_CONNECTION_FOOTERS_SENDING;
+ continue;
+ case MHD_CONNECTION_FOOTERS_SENDING:
+ /* no default action */
+ break;
+ case MHD_CONNECTION_FOOTERS_SENT:
+ if (MHD_HTTP_PROCESSING == connection->responseCode)
+ {
+ /* After this type of response, we allow sending another! */
+ connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
+ MHD_destroy_response (connection->response);
+ connection->response = NULL;
+ /* FIXME: maybe partially reset memory pool? */
+ continue;
+ }
+ MHD_destroy_response (connection->response);
+ connection->response = NULL;
+ if ( (NULL != daemon->notify_completed) &&
+ (connection->client_aware) )
+ {
+ daemon->notify_completed (daemon->notify_completed_cls,
+ connection,
+ &connection->client_context,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ }
+ connection->client_aware = false;
+ if ( (MHD_CONN_USE_KEEPALIVE != connection->keepalive) ||
+ (connection->read_closed) )
+ {
+ /* have to close for some reason */
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ MHD_pool_destroy (connection->pool);
+ connection->pool = NULL;
+ connection->read_buffer = NULL;
+ connection->read_buffer_size = 0;
+ connection->read_buffer_offset = 0;
+ }
+ else
+ {
+ /* can try to keep-alive */
+
+ connection->version = NULL;
+ connection->state = MHD_CONNECTION_INIT;
+ connection->last = NULL;
+ connection->colon = NULL;
+ connection->header_size = 0;
+ connection->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
+ /* Reset the read buffer to the starting size,
+ preserving the bytes we have already read. */
+ connection->read_buffer
+ = MHD_pool_reset (connection->pool,
+ connection->read_buffer,
+ connection->read_buffer_offset,
+ connection->daemon->pool_size / 2);
+ connection->read_buffer_size
+ = connection->daemon->pool_size / 2;
+ }
+ connection->client_context = NULL;
+ connection->continue_message_write_offset = 0;
+ connection->responseCode = 0;
+ connection->headers_received = NULL;
+ connection->headers_received_tail = NULL;
+ connection->response_write_position = 0;
+ connection->have_chunked_upload = false;
+ connection->current_chunk_size = 0;
+ connection->current_chunk_offset = 0;
+ connection->method = NULL;
+ connection->url = NULL;
+ connection->write_buffer = NULL;
+ connection->write_buffer_size = 0;
+ connection->write_buffer_send_offset = 0;
+ connection->write_buffer_append_offset = 0;
+ /* iov (if any) was deallocated by MHD_pool_reset */
+ memset (&connection->resp_iov, 0, sizeof(connection->resp_iov));
+ continue;
+ case MHD_CONNECTION_CLOSED:
+ cleanup_connection (connection);
+ connection->in_idle = false;
+ return MHD_NO;
#ifdef UPGRADE_SUPPORT
- case MHD_CONNECTION_UPGRADE:
- connection->in_idle = false;
- return MHD_YES; /* keep open */
+ case MHD_CONNECTION_UPGRADE:
+ connection->in_idle = false;
+ return MHD_YES; /* keep open */
#endif /* UPGRADE_SUPPORT */
- default:
- EXTRA_CHECK (0);
- break;
- }
+ default:
+ mhd_assert (0);
break;
}
+ break;
+ }
if (! connection->suspended)
+ {
+ time_t timeout;
+ timeout = connection->connection_timeout;
+ if ( (0 != timeout) &&
+ (timeout < (MHD_monotonic_sec_counter ()
+ - connection->last_activity)) )
{
- time_t timeout;
- timeout = connection->connection_timeout;
- if ( (0 != timeout) &&
- (timeout < (MHD_monotonic_sec_counter() - connection->last_activity)) )
- {
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
- connection->in_idle = false;
- return MHD_YES;
- }
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
+ connection->in_idle = false;
+ return MHD_YES;
}
+ }
MHD_connection_update_event_loop_info (connection);
ret = MHD_YES;
#ifdef EPOLL_SUPPORT
if ( (! connection->suspended) &&
(0 != (daemon->options & MHD_USE_EPOLL)) )
- {
- ret = MHD_connection_epoll_update_ (connection);
- }
+ {
+ ret = MHD_connection_epoll_update_ (connection);
+ }
#endif /* EPOLL_SUPPORT */
connection->in_idle = false;
return ret;
@@ -3390,7 +3841,7 @@
* @return #MHD_YES if we should continue to process the
* connection (not dead yet), #MHD_NO if it died
*/
-int
+enum MHD_Result
MHD_connection_epoll_update_ (struct MHD_Connection *connection)
{
struct MHD_Daemon *daemon = connection->daemon;
@@ -3400,33 +3851,35 @@
(0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->event_loop_info) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) ||
- ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) )
+ ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) )
+ {
+ /* add to epoll set */
+ struct epoll_event event;
+
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = connection;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ connection->socket_fd,
+ &event))
{
- /* add to epoll set */
- struct epoll_event event;
-
- event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
- event.data.ptr = connection;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- connection->socket_fd,
- &event))
- {
-#ifdef HAVE_MESSAGES
- if (0 != (daemon->options & MHD_USE_ERROR_LOG))
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- connection->state = MHD_CONNECTION_CLOSED;
- cleanup_connection (connection);
- return MHD_NO;
- }
- connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+#ifdef HAVE_MESSAGES
+ if (0 != (daemon->options & MHD_USE_ERROR_LOG))
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ connection->state = MHD_CONNECTION_CLOSED;
+ cleanup_connection (connection);
+ return MHD_NO;
}
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
return MHD_YES;
}
+
+
#endif
@@ -3438,9 +3891,7 @@
void
MHD_set_http_callbacks_ (struct MHD_Connection *connection)
{
- connection->read_handler = &MHD_connection_handle_read;
- connection->write_handler = &MHD_connection_handle_write;
- connection->idle_handler = &MHD_connection_handle_idle;
+ connection->recv_cls = &recv_param_adapter;
}
@@ -3460,46 +3911,48 @@
...)
{
switch (info_type)
- {
+ {
#ifdef HTTPS_SUPPORT
- case MHD_CONNECTION_INFO_CIPHER_ALGO:
- if (NULL == connection->tls_session)
- return NULL;
- connection->cipher = gnutls_cipher_get (connection->tls_session);
- return (const union MHD_ConnectionInfo *) &connection->cipher;
- case MHD_CONNECTION_INFO_PROTOCOL:
- if (NULL == connection->tls_session)
- return NULL;
- connection->protocol = gnutls_protocol_get_version (connection->tls_session);
- return (const union MHD_ConnectionInfo *) &connection->protocol;
- case MHD_CONNECTION_INFO_GNUTLS_SESSION:
- if (NULL == connection->tls_session)
- return NULL;
- return (const union MHD_ConnectionInfo *) &connection->tls_session;
-#endif /* HTTPS_SUPPORT */
- case MHD_CONNECTION_INFO_CLIENT_ADDRESS:
- return (const union MHD_ConnectionInfo *) &connection->addr;
- case MHD_CONNECTION_INFO_DAEMON:
- return (const union MHD_ConnectionInfo *) &connection->daemon;
- case MHD_CONNECTION_INFO_CONNECTION_FD:
- return (const union MHD_ConnectionInfo *) &connection->socket_fd;
- case MHD_CONNECTION_INFO_SOCKET_CONTEXT:
- return (const union MHD_ConnectionInfo *) &connection->socket_context;
- case MHD_CONNECTION_INFO_CONNECTION_SUSPENDED:
- connection->suspended_dummy = connection->suspended ? MHD_YES : MHD_NO;
- return (const union MHD_ConnectionInfo *) &connection->suspended_dummy;
- case MHD_CONNECTION_INFO_CONNECTION_TIMEOUT:
- connection->connection_timeout_dummy = (unsigned int)connection->connection_timeout;
- return (const union MHD_ConnectionInfo *) &connection->connection_timeout_dummy;
- case MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE:
- if ( (MHD_CONNECTION_HEADERS_RECEIVED > connection->state) ||
- (MHD_CONNECTION_CLOSED == connection->state) ||
- (MHD_CONNECTION_IN_CLEANUP == connection->state) )
- return NULL; /* invalid, too early! */
- return (const union MHD_ConnectionInfo *) &connection->header_size;
- default:
+ case MHD_CONNECTION_INFO_CIPHER_ALGO:
+ if (NULL == connection->tls_session)
return NULL;
- }
+ connection->cipher = gnutls_cipher_get (connection->tls_session);
+ return (const union MHD_ConnectionInfo *) &connection->cipher;
+ case MHD_CONNECTION_INFO_PROTOCOL:
+ if (NULL == connection->tls_session)
+ return NULL;
+ connection->protocol = gnutls_protocol_get_version (
+ connection->tls_session);
+ return (const union MHD_ConnectionInfo *) &connection->protocol;
+ case MHD_CONNECTION_INFO_GNUTLS_SESSION:
+ if (NULL == connection->tls_session)
+ return NULL;
+ return (const union MHD_ConnectionInfo *) &connection->tls_session;
+#endif /* HTTPS_SUPPORT */
+ case MHD_CONNECTION_INFO_CLIENT_ADDRESS:
+ return (const union MHD_ConnectionInfo *) &connection->addr;
+ case MHD_CONNECTION_INFO_DAEMON:
+ return (const union MHD_ConnectionInfo *) &connection->daemon;
+ case MHD_CONNECTION_INFO_CONNECTION_FD:
+ return (const union MHD_ConnectionInfo *) &connection->socket_fd;
+ case MHD_CONNECTION_INFO_SOCKET_CONTEXT:
+ return (const union MHD_ConnectionInfo *) &connection->socket_context;
+ case MHD_CONNECTION_INFO_CONNECTION_SUSPENDED:
+ connection->suspended_dummy = connection->suspended ? MHD_YES : MHD_NO;
+ return (const union MHD_ConnectionInfo *) &connection->suspended_dummy;
+ case MHD_CONNECTION_INFO_CONNECTION_TIMEOUT:
+ connection->connection_timeout_dummy = (unsigned
+ int) connection->connection_timeout;
+ return (const union MHD_ConnectionInfo *) &connection->
+ connection_timeout_dummy;
+ case MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE:
+ if ( (MHD_CONNECTION_HEADERS_RECEIVED > connection->state) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ return NULL; /* invalid, too early! */
+ return (const union MHD_ConnectionInfo *) &connection->header_size;
+ default:
+ return NULL;
+ }
}
@@ -3512,55 +3965,58 @@
* @return #MHD_YES on success, #MHD_NO if setting the option failed
* @ingroup specialized
*/
-int
+enum MHD_Result
MHD_set_connection_option (struct MHD_Connection *connection,
- enum MHD_CONNECTION_OPTION option,
- ...)
+ enum MHD_CONNECTION_OPTION option,
+ ...)
{
va_list ap;
struct MHD_Daemon *daemon;
daemon = connection->daemon;
switch (option)
+ {
+ case MHD_CONNECTION_OPTION_TIMEOUT:
+ if (0 == connection->connection_timeout)
+ connection->last_activity = MHD_monotonic_sec_counter ();
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (! connection->suspended) )
{
- case MHD_CONNECTION_OPTION_TIMEOUT:
- if (0 == connection->connection_timeout)
- connection->last_activity = MHD_monotonic_sec_counter();
-
- MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
- if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (! connection->suspended) )
- {
- if (connection->connection_timeout == daemon->connection_timeout)
- XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
- else
- XDLL_remove (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- connection);
- }
- va_start (ap, option);
- connection->connection_timeout = va_arg (ap,
- unsigned int);
- va_end (ap);
- if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (! connection->suspended) )
- {
- if (connection->connection_timeout == daemon->connection_timeout)
- XDLL_insert (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
- else
- XDLL_insert (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- connection);
- }
- MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
- return MHD_YES;
- default:
- return MHD_NO;
+ if (connection->connection_timeout == daemon->connection_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
+ va_start (ap, option);
+ connection->connection_timeout = va_arg (ap,
+ unsigned int);
+ va_end (ap);
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (! connection->suspended) )
+ {
+ if (connection->connection_timeout == daemon->connection_timeout)
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_insert (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
}
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ return MHD_YES;
+ default:
+ return MHD_NO;
+ }
}
@@ -3575,52 +4031,78 @@
* #MHD_YES on success or if message has been queued
* @ingroup response
*/
-int
+enum MHD_Result
MHD_queue_response (struct MHD_Connection *connection,
unsigned int status_code,
struct MHD_Response *response)
{
-#ifdef UPGRADE_SUPPORT
struct MHD_Daemon *daemon;
-#endif /* UPGRADE_SUPPORT */
if ( (NULL == connection) ||
(NULL == response) ||
(NULL != connection->response) ||
( (MHD_CONNECTION_HEADERS_PROCESSED != connection->state) &&
- (MHD_CONNECTION_FOOTERS_RECEIVED != connection->state) ) )
+ (MHD_CONNECTION_FOOTERS_RECEIVED != connection->state) ) )
return MHD_NO;
-#ifdef UPGRADE_SUPPORT
daemon = connection->daemon;
+
+ if (daemon->shutdown)
+ return MHD_YES; /* If daemon was shut down in parallel,
+ * response will be aborted now or on later stage. */
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if ( (! connection->suspended) &&
+ (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
+ (! MHD_thread_ID_match_current_ (connection->pid)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Attempted to queue response on wrong thread!\n"));
+#endif
+ return MHD_NO;
+ }
+#endif
+#ifdef UPGRADE_SUPPORT
if ( (NULL != response->upgrade_handler) &&
(0 == (daemon->options & MHD_ALLOW_UPGRADE)) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
if ( (MHD_HTTP_SWITCHING_PROTOCOLS != status_code) &&
(NULL != response->upgrade_handler) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Application used invalid status code for 'upgrade' response!\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Application used invalid status code for 'upgrade' response!\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
#endif /* UPGRADE_SUPPORT */
MHD_increment_response_rc (response);
connection->response = response;
connection->responseCode = status_code;
-#if LINUX
+#if defined(_MHD_HAVE_SENDFILE)
if ( (response->fd == -1) ||
- (0 != (connection->daemon->options & MHD_USE_TLS)) )
+ (response->is_pipe) ||
+ (0 != (connection->daemon->options & MHD_USE_TLS))
+#if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \
+ defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE)
+ || (! daemon->sigpipe_blocked && ! connection->sk_spipe_suppress)
+#endif /* MHD_SEND_SPIPE_SUPPRESS_NEEDED &&
+ MHD_SEND_SPIPE_SUPPRESS_POSSIBLE */
+ )
connection->resp_sender = MHD_resp_sender_std;
else
connection->resp_sender = MHD_resp_sender_sendfile;
-#endif /* LINUX */
+#endif /* _MHD_HAVE_SENDFILE */
+ /* FIXME: if 'is_pipe' is set, TLS is off, and we have *splice*, we could use splice()
+ to avoid two user-space copies... */
if ( ( (NULL != connection->method) &&
(MHD_str_equal_caseless_ (connection->method,
@@ -3628,26 +4110,23 @@
(MHD_HTTP_OK > status_code) ||
(MHD_HTTP_NO_CONTENT == status_code) ||
(MHD_HTTP_NOT_MODIFIED == status_code) )
- {
- /* if this is a "HEAD" request, or a status code for
- which a body is not allowed, pretend that we
- have already sent the full message body. */
- connection->response_write_position = response->total_size;
- }
- if ( (MHD_CONNECTION_HEADERS_PROCESSED == connection->state) &&
- (NULL != connection->method) &&
- ( (MHD_str_equal_caseless_ (connection->method,
- MHD_HTTP_METHOD_POST)) ||
- (MHD_str_equal_caseless_ (connection->method,
- MHD_HTTP_METHOD_PUT))) )
- {
- /* response was queued "early", refuse to read body / footers or
- further requests! */
- connection->read_closed = true;
- connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
- }
+ {
+ /* if this is a "HEAD" request, or a status code for
+ which a body is not allowed, pretend that we
+ have already sent the full message body. */
+ connection->response_write_position = response->total_size;
+ }
+ if (MHD_CONNECTION_HEADERS_PROCESSED == connection->state)
+ {
+ /* response was queued "early", refuse to read body / footers or
+ further requests! */
+ connection->read_closed = true;
+ connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
+ connection->remaining_upload_size = 0;
+ }
if (! connection->in_idle)
(void) MHD_connection_handle_idle (connection);
+ MHD_update_last_activity_ (connection);
return MHD_YES;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/connection.h
^
|
@@ -30,6 +30,52 @@
#include "internal.h"
+/**
+ * Error code similar to EGAIN or EINTR
+ */
+#define MHD_ERR_AGAIN_ (-3073)
+
+/**
+ * Connection was hard-closed by remote peer.
+ */
+#define MHD_ERR_CONNRESET_ (-3074)
+
+/**
+ * Connection is not connected anymore due to
+ * network error or any other reason.
+ */
+#define MHD_ERR_NOTCONN_ (-3075)
+
+/**
+ * "Not enough memory" error code
+ */
+#define MHD_ERR_NOMEM_ (-3076)
+
+/**
+ * "Bad FD" error code
+ */
+#define MHD_ERR_BADF_ (-3077)
+
+/**
+ * Error code similar to EINVAL
+ */
+#define MHD_ERR_INVAL_ (-3078)
+
+/**
+ * Argument values are not supported
+ */
+#define MHD_ERR_OPNOTSUPP_ (-3079)
+
+/**
+ * Socket is shut down for writing or no longer connected
+ */
+#define MHD_ERR_PIPE_ (-3080)
+
+/**
+ * General TLS encryption or decryption error
+ */
+#define MHD_ERR_TLS_ (-4097)
+
/**
* Set callbacks for this connection to those for HTTP.
@@ -47,10 +93,8 @@
* call this function to handle reads.
*
* @param connection connection to handle
- * @return always MHD_YES (we should continue to process the
- * connection)
*/
-int
+void
MHD_connection_handle_read (struct MHD_Connection *connection);
@@ -61,10 +105,8 @@
* call this function
*
* @param connection connection to handle
- * @return always MHD_YES (we should continue to process the
- * connection)
*/
-int
+void
MHD_connection_handle_write (struct MHD_Connection *connection);
@@ -77,10 +119,10 @@
* recv(), send() and response.
*
* @param connection connection to handle
- * @return MHD_YES if we should continue to process the
- * connection (not dead yet), MHD_NO if it died
+ * @return #MHD_YES if we should continue to process the
+ * connection (not dead yet), #MHD_NO if it died
*/
-int
+enum MHD_Result
MHD_connection_handle_idle (struct MHD_Connection *connection);
@@ -116,8 +158,9 @@
*/
void
MHD_connection_finish_forward_ (struct MHD_Connection *connection);
+
#else /* ! HTTPS_SUPPORT */
-#define MHD_connection_finish_forward_(conn) (void)conn
+#define MHD_connection_finish_forward_(conn) (void) conn
#endif /* ! HTTPS_SUPPORT */
@@ -127,11 +170,12 @@
* the epoll set if needed.
*
* @param connection connection to process
- * @return MHD_YES if we should continue to process the
- * connection (not dead yet), MHD_NO if it died
+ * @return #MHD_YES if we should continue to process the
+ * connection (not dead yet), #MHD_NO if it died
*/
-int
+enum MHD_Result
MHD_connection_epoll_update_ (struct MHD_Connection *connection);
+
#endif
/**
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/connection_https.c
^
|
@@ -1,6 +1,7 @@
/*
This file is part of libmicrohttpd
Copyright (C) 2007, 2008, 2010 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2015-2021 Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -24,6 +25,7 @@
* compiled if ENABLE_HTTPS is set.
* @author Sagie Amir
* @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
*/
#include "internal.h"
@@ -33,136 +35,136 @@
#include "response.h"
#include "mhd_mono_clock.h"
#include <gnutls/gnutls.h>
+#include "mhd_send.h"
/**
- * Give gnuTLS chance to work on the TLS handshake.
+ * Callback for receiving data from the socket.
*
- * @param connection connection to handshake on
- * @return #MHD_YES on error or if the handshake is progressing
- * #MHD_NO if the handshake has completed successfully
- * and we should start to read/write data
+ * @param connection the MHD_Connection structure
+ * @param other where to write received data to
+ * @param i maximum size of other (in bytes)
+ * @return positive value for number of bytes actually received or
+ * negative value for error number MHD_ERR_xxx_
*/
-static int
-run_tls_handshake (struct MHD_Connection *connection)
+static ssize_t
+recv_tls_adapter (struct MHD_Connection *connection,
+ void *other,
+ size_t i)
{
- int ret;
-
- if (MHD_TLS_CONNECTION_INIT == connection->state)
- {
- ret = gnutls_handshake (connection->tls_session);
- if (ret == GNUTLS_E_SUCCESS)
- {
- /* set connection state to enable HTTP processing */
- connection->state = MHD_CONNECTION_INIT;
- MHD_update_last_activity_ (connection);
- return MHD_NO;
- }
- if ( (GNUTLS_E_AGAIN == ret) ||
- (GNUTLS_E_INTERRUPTED == ret) )
- {
- /* handshake not done */
- return MHD_YES;
- }
- /* handshake failed */
-#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Error: received handshake message out of context\n"));
-#endif
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_WITH_ERROR);
- return MHD_YES;
- }
- return MHD_NO;
-}
-
+ ssize_t res;
-/**
- * This function handles a particular SSL/TLS connection when
- * it has been determined that there is data to be read off a
- * socket. Message processing is done by message type which is
- * determined by peeking into the first message type byte of the
- * stream.
- *
- * Error message handling: all fatal level messages cause the
- * connection to be terminated.
- *
- * Application data is forwarded to the underlying daemon for
- * processing.
- *
- * @param connection the source connection
- * @return always #MHD_YES (we should continue to process the connection)
- */
-static int
-MHD_tls_connection_handle_read (struct MHD_Connection *connection)
-{
- if (MHD_YES == run_tls_handshake (connection))
- return MHD_YES;
- return MHD_connection_handle_read (connection);
-}
+ if (i > SSIZE_MAX)
+ i = SSIZE_MAX;
+ res = gnutls_record_recv (connection->tls_session,
+ other,
+ i);
+ if ( (GNUTLS_E_AGAIN == res) ||
+ (GNUTLS_E_INTERRUPTED == res) )
+ {
+#ifdef EPOLL_SUPPORT
+ if (GNUTLS_E_AGAIN == res)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
+#endif
+ /* Any network errors means that buffer is empty. */
+ connection->tls_read_ready = false;
+ return MHD_ERR_AGAIN_;
+ }
+ if (res < 0)
+ {
+ connection->tls_read_ready = false;
+ if ( (GNUTLS_E_DECRYPTION_FAILED == res) ||
+ (GNUTLS_E_INVALID_SESSION == res) ||
+ (GNUTLS_E_DECOMPRESSION_FAILED == res) ||
+ (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER == res) ||
+ (GNUTLS_E_UNSUPPORTED_VERSION_PACKET == res) ||
+ (GNUTLS_E_UNEXPECTED_PACKET_LENGTH == res) ||
+ (GNUTLS_E_UNEXPECTED_PACKET == res) ||
+ (GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET == res) ||
+ (GNUTLS_E_EXPIRED == res) ||
+ (GNUTLS_E_REHANDSHAKE == res) )
+ return MHD_ERR_TLS_;
+ if ( (GNUTLS_E_PULL_ERROR == res) ||
+ (GNUTLS_E_INTERNAL_ERROR == res) ||
+ (GNUTLS_E_CRYPTODEV_IOCTL_ERROR == res) ||
+ (GNUTLS_E_CRYPTODEV_DEVICE_ERROR == res) )
+ return MHD_ERR_PIPE_;
+ if (GNUTLS_E_PREMATURE_TERMINATION == res)
+ return MHD_ERR_CONNRESET_;
+ if (GNUTLS_E_MEMORY_ERROR == res)
+ return MHD_ERR_NOMEM_;
+ /* Treat any other error as a hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
-/**
- * This function was created to handle writes to sockets when it has
- * been determined that the socket can be written to. This function
- * will forward all write requests to the underlying daemon unless
- * the connection has been marked for closing.
- *
- * @return always #MHD_YES (we should continue to process the connection)
- */
-static int
-MHD_tls_connection_handle_write (struct MHD_Connection *connection)
-{
- if (MHD_YES == run_tls_handshake (connection))
- return MHD_YES;
- return MHD_connection_handle_write (connection);
+#ifdef EPOLL_SUPPORT
+ /* Unlike non-TLS connections, do not reset "read-ready" if
+ * received amount smaller than provided amount, as TLS
+ * connections may receive data by fixed-size chunks. */
+#endif /* EPOLL_SUPPORT */
+
+ /* Check whether TLS buffers still have some unread data. */
+ connection->tls_read_ready = ( ((size_t) res == i) &&
+ (0 != gnutls_record_check_pending (
+ connection->tls_session)) );
+ return res;
}
/**
- * This function was created to handle per-connection processing that
- * has to happen even if the socket cannot be read or written to. All
- * implementations (multithreaded, external select, internal select)
- * call this function.
+ * Give gnuTLS chance to work on the TLS handshake.
*
- * @param connection being handled
- * @return #MHD_YES if we should continue to process the
- * connection (not dead yet), #MHD_NO if it died
+ * @param connection connection to handshake on
+ * @return true if the handshake has completed successfully
+ * and we should start to read/write data,
+ * false is handshake in progress or in case
+ * of error
*/
-static int
-MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
+bool
+MHD_run_tls_handshake_ (struct MHD_Connection *connection)
{
- time_t timeout;
+ int ret;
-#if DEBUG_STATES
- MHD_DLOG (connection->daemon,
- _("In function %s handling connection at state: %s\n"),
- __FUNCTION__,
- MHD_state_to_string (connection->state));
+ if ((MHD_TLS_CONN_INIT == connection->tls_state) ||
+ (MHD_TLS_CONN_HANDSHAKING == connection->tls_state))
+ {
+#if 0
+ /* According to real-live testing, Nagel's Algorithm is not blocking
+ * partial packets on just connected sockets on modern OSes. As TLS setup
+ * is performed as the fist action upon socket connection, the next
+ * optimisation typically is not required. If any specific OS will
+ * require this optimization, it could be enabled by allowing the next
+ * lines for this specific OS. */
+ if (_MHD_ON != connection->sk_nodelay)
+ MHD_connection_set_nodelay_state_ (connection, true);
#endif
- if (connection->suspended)
- return MHD_connection_handle_idle (connection);
- switch (connection->state)
+ ret = gnutls_handshake (connection->tls_session);
+ if (ret == GNUTLS_E_SUCCESS)
{
- /* on newly created connections we might reach here before any reply has been received */
- case MHD_TLS_CONNECTION_INIT:
- break;
- /* close connection if necessary */
- case MHD_CONNECTION_CLOSED:
- return MHD_connection_handle_idle (connection);
- default:
- return MHD_connection_handle_idle (connection);
+ /* set connection TLS state to enable HTTP processing */
+ connection->tls_state = MHD_TLS_CONN_CONNECTED;
+ MHD_update_last_activity_ (connection);
+ return true;
}
- timeout = connection->connection_timeout;
- if ( (timeout != 0) &&
- (timeout < (MHD_monotonic_sec_counter() - connection->last_activity)))
- MHD_connection_close_ (connection,
- MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
-#ifdef EPOLL_SUPPORT
- return MHD_connection_epoll_update_ (connection);
-#else
- return MHD_YES;
+ if ( (GNUTLS_E_AGAIN == ret) ||
+ (GNUTLS_E_INTERRUPTED == ret) )
+ {
+ connection->tls_state = MHD_TLS_CONN_HANDSHAKING;
+ /* handshake not done */
+ return false;
+ }
+ /* handshake failed */
+ connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Error: received handshake message out of context.\n"));
#endif
+ MHD_connection_close_ (connection,
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+ return false;
+ }
+ return true;
}
@@ -175,9 +177,7 @@
void
MHD_set_https_callbacks (struct MHD_Connection *connection)
{
- connection->read_handler = &MHD_tls_connection_handle_read;
- connection->write_handler = &MHD_tls_connection_handle_write;
- connection->idle_handler = &MHD_tls_connection_handle_idle;
+ connection->recv_cls = &recv_tls_adapter;
}
@@ -185,17 +185,31 @@
* Initiate shutdown of TLS layer of connection.
*
* @param connection to use
- * @return #MHD_YES if succeed, #MHD_NO otherwise.
+ * @return true if succeed, false otherwise.
*/
-int
+bool
MHD_tls_connection_shutdown (struct MHD_Connection *connection)
{
- if (connection->tls_closed)
- return MHD_NO;
-
- connection->tls_closed = true;
- return (GNUTLS_E_SUCCESS == gnutls_bye(connection->tls_session, GNUTLS_SHUT_WR)) ?
- MHD_YES : MHD_NO;
+ if (MHD_TLS_CONN_WR_CLOSED > connection->tls_state)
+ {
+ const int res =
+ gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
+ if (GNUTLS_E_SUCCESS == res)
+ {
+ connection->tls_state = MHD_TLS_CONN_WR_CLOSED;
+ return true;
+ }
+ if ((GNUTLS_E_AGAIN == res) ||
+ (GNUTLS_E_INTERRUPTED == res))
+ {
+ connection->tls_state = MHD_TLS_CONN_WR_CLOSING;
+ return true;
+ }
+ else
+ connection->tls_state = MHD_TLS_CONN_TLS_FAILED;
+ }
+ return false;
}
+
/* end of connection_https.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/connection_https.h
^
|
@@ -35,18 +35,46 @@
*
* @param connection which callbacks should be modified
*/
-void
+void
MHD_set_https_callbacks (struct MHD_Connection *connection);
/**
+ * Give gnuTLS chance to work on the TLS handshake.
+ *
+ * @param connection connection to handshake on
+ * @return true if the handshake has completed successfully
+ * and we should start to read/write data,
+ * false is handshake in progress or in case
+ * of error
+ */
+bool
+MHD_run_tls_handshake_ (struct MHD_Connection *connection);
+
+
+/**
* Initiate shutdown of TLS layer of connection.
*
* @param connection to use
- * @return #MHD_YES if succeed, #MHD_NO otherwise.
+ * @return true if succeed, false otherwise.
*/
-int
+bool
MHD_tls_connection_shutdown (struct MHD_Connection *connection);
+
+/**
+ * Callback for writing data to the socket.
+ *
+ * @param connection the MHD connection structure
+ * @param other data to write
+ * @param i number of bytes to write
+ * @return positive value for number of bytes actually sent or
+ * negative value for error number MHD_ERR_xxx_
+ */
+ssize_t
+send_tls_adapter (struct MHD_Connection *connection,
+ const void *other,
+ size_t i);
+
#endif /* HTTPS_SUPPORT */
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/daemon.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,9 @@
* @author Karlson2k (Evgeny Grin)
*/
#include "platform.h"
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
#include "mhd_threads.h"
+#endif
#include "internal.h"
#include "response.h"
#include "connection.h"
@@ -34,10 +36,13 @@
#include "mhd_limits.h"
#include "autoinit_funcs.h"
#include "mhd_mono_clock.h"
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
#include "mhd_locks.h"
+#endif
#include "mhd_sockets.h"
#include "mhd_itc.h"
#include "mhd_compat.h"
+#include "mhd_send.h"
#if HAVE_SEARCH_H
#include <search.h>
@@ -47,20 +52,24 @@
#ifdef HTTPS_SUPPORT
#include "connection_https.h"
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#endif /* HTTPS_SUPPORT */
-#ifdef LINUX
-#include <sys/sendfile.h>
-#endif
-
-#ifdef _WIN32
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif /* !WIN32_LEAN_AND_MEAN */
#include <windows.h>
#endif
+#ifdef MHD_USE_POSIX_THREADS
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif /* HAVE_SIGNAL_H */
+#endif /* MHD_USE_POSIX_THREADS */
+
/**
* Default connection limit.
*/
@@ -75,18 +84,6 @@
*/
#define MHD_POOL_SIZE_DEFAULT (32 * 1024)
-/**
- * Print extra messages with reasons for closing
- * sockets? (only adds non-error messages).
- */
-#define DEBUG_CLOSE MHD_NO
-
-/**
- * Print extra messages when establishing
- * connections? (only adds non-error messages).
- */
-#define DEBUG_CONNECT MHD_NO
-
/* Forward declarations. */
@@ -104,16 +101,17 @@
#ifdef EPOLL_SUPPORT
/**
- * Do epoll()-based processing (this function is allowed to
- * block if @a may_block is set to #MHD_YES).
+ * Do epoll()-based processing.
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_epoll (struct MHD_Daemon *daemon,
- int may_block);
+ int32_t millisec);
#endif /* EPOLL_SUPPORT */
@@ -128,16 +126,21 @@
*/
static void
mhd_panic_std (void *cls,
- const char *file,
- unsigned int line,
- const char *reason)
+ const char *file,
+ unsigned int line,
+ const char *reason)
{
+ (void) cls; /* Mute compiler warning. */
#ifdef HAVE_MESSAGES
fprintf (stderr,
- _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
- file,
+ _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
+ file,
line,
reason);
+#else /* ! HAVE_MESSAGES */
+ (void) file; /* Mute compiler warning. */
+ (void) line; /* Mute compiler warning. */
+ (void) reason; /* Mute compiler warning. */
#endif
abort ();
}
@@ -146,19 +149,104 @@
/**
* Handler for fatal errors.
*/
-MHD_PanicCallback mhd_panic;
+MHD_PanicCallback mhd_panic = (MHD_PanicCallback) NULL;
/**
* Closure argument for #mhd_panic.
*/
-void *mhd_panic_cls;
+void *mhd_panic_cls = NULL;
+
+/**
+ * Globally initialise library.
+ */
+void
+MHD_init (void);
+
-#ifdef _WIN32
+#if defined(MHD_WINSOCK_SOCKETS)
/**
* Track initialization of winsock
*/
static int mhd_winsock_inited_ = 0;
+#endif /* MHD_WINSOCK_SOCKETS */
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+/**
+ * Do nothing - global initialisation is
+ * performed by library constructor.
+ */
+#define MHD_check_global_init_() (void) 0
+#else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+/**
+ * Track global initialisation
+ */
+volatile int global_init_count = 0;
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+/**
+ * Global initialisation mutex
+ */
+MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+#endif
+
+
+/**
+ * Check whether global initialisation was performed
+ * and call initialiser if necessary.
+ */
+void
+MHD_check_global_init_ (void)
+{
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_lock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
+#endif
+ if (0 == global_init_count++)
+ MHD_init ();
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
+ MHD_mutex_unlock_chk_ (&global_init_mutex_);
+#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
#endif
+}
+
+
+#endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
+
+#ifdef HAVE_MESSAGES
+/**
+ * Default logger function
+ */
+static void
+MHD_default_logger_ (void *cls,
+ const char *fm,
+ va_list ap)
+{
+ vfprintf ((FILE*) cls, fm, ap);
+#ifdef _DEBUG
+ fflush ((FILE*) cls);
+#endif /* _DEBUG */
+}
+
+
+#endif /* HAVE_MESSAGES */
+
+
+/**
+ * Free the memory given by @a ptr. Calls "free(ptr)". This function
+ * should be used to free the username returned by
+ * #MHD_digest_auth_get_username().
+ *
+ * @param ptr pointer to free.
+ */
+_MHD_EXTERN void
+MHD_free (void *ptr)
+{
+ free (ptr);
+}
/**
@@ -219,7 +307,11 @@
static void
MHD_ip_count_lock (struct MHD_Daemon *daemon)
{
- MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex);
+#else
+ (void) daemon;
+#endif
}
@@ -231,7 +323,11 @@
static void
MHD_ip_count_unlock (struct MHD_Daemon *daemon)
{
- MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex);
+#else
+ (void) daemon;
+#endif
}
@@ -263,39 +359,39 @@
* @param key where to store the parsed address
* @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type)
*/
-static int
+static enum MHD_Result
MHD_ip_addr_to_key (const struct sockaddr *addr,
- socklen_t addrlen,
- struct MHD_IPCount *key)
+ socklen_t addrlen,
+ struct MHD_IPCount *key)
{
- memset(key,
- 0,
- sizeof(*key));
+ memset (key,
+ 0,
+ sizeof(*key));
/* IPv4 addresses */
if (sizeof (struct sockaddr_in) == addrlen)
- {
- const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
+ {
+ const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
- key->family = AF_INET;
- memcpy (&key->addr.ipv4,
- &addr4->sin_addr,
- sizeof(addr4->sin_addr));
- return MHD_YES;
- }
+ key->family = AF_INET;
+ memcpy (&key->addr.ipv4,
+ &addr4->sin_addr,
+ sizeof(addr4->sin_addr));
+ return MHD_YES;
+ }
#if HAVE_INET6
/* IPv6 addresses */
if (sizeof (struct sockaddr_in6) == addrlen)
- {
- const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
+ {
+ const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
- key->family = AF_INET6;
- memcpy (&key->addr.ipv6,
- &addr6->sin6_addr,
- sizeof(addr6->sin6_addr));
- return MHD_YES;
- }
+ key->family = AF_INET6;
+ memcpy (&key->addr.ipv6,
+ &addr6->sin6_addr,
+ sizeof(addr6->sin6_addr));
+ return MHD_YES;
+ }
#endif
/* Some other address */
@@ -314,15 +410,15 @@
* @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit.
* Also returns #MHD_NO if fails to allocate memory.
*/
-static int
+static enum MHD_Result
MHD_ip_limit_add (struct MHD_Daemon *daemon,
- const struct sockaddr *addr,
- socklen_t addrlen)
+ const struct sockaddr *addr,
+ socklen_t addrlen)
{
struct MHD_IPCount *key;
void **nodep;
void *node;
- int result;
+ enum MHD_Result result;
daemon = MHD_get_master (daemon);
/* Ignore if no connection limit assigned */
@@ -336,35 +432,35 @@
if (MHD_NO == MHD_ip_addr_to_key (addr,
addrlen,
key))
- {
- /* Allow unhandled address types through */
- free (key);
- return MHD_YES;
- }
+ {
+ /* Allow unhandled address types through */
+ free (key);
+ return MHD_YES;
+ }
MHD_ip_count_lock (daemon);
/* Search for the IP address */
if (NULL == (nodep = tsearch (key,
- &daemon->per_ip_connection_count,
- &MHD_ip_addr_compare)))
- {
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare)))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to add IP connection count node\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to add IP connection count node.\n"));
#endif
- MHD_ip_count_unlock (daemon);
- free (key);
- return MHD_NO;
- }
+ MHD_ip_count_unlock (daemon);
+ free (key);
+ return MHD_NO;
+ }
node = *nodep;
/* If we got an existing node back, free the one we created */
if (node != key)
- free(key);
+ free (key);
key = (struct MHD_IPCount *) node;
/* Test if there is room for another connection; if so,
* increment count */
result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
- if (MHD_YES == result)
+ if (MHD_NO != result)
++key->count;
MHD_ip_count_unlock (daemon);
@@ -382,8 +478,8 @@
*/
static void
MHD_ip_limit_del (struct MHD_Daemon *daemon,
- const struct sockaddr *addr,
- socklen_t addrlen)
+ const struct sockaddr *addr,
+ socklen_t addrlen)
{
struct MHD_IPCount search_key;
struct MHD_IPCount *found_key;
@@ -403,27 +499,27 @@
/* Search for the IP address */
if (NULL == (nodep = tfind (&search_key,
- &daemon->per_ip_connection_count,
- &MHD_ip_addr_compare)))
- {
- /* Something's wrong if we couldn't find an IP address
- * that was previously added */
- MHD_PANIC (_("Failed to find previously-added IP address\n"));
- }
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare)))
+ {
+ /* Something's wrong if we couldn't find an IP address
+ * that was previously added */
+ MHD_PANIC (_ ("Failed to find previously-added IP address.\n"));
+ }
found_key = (struct MHD_IPCount *) *nodep;
/* Validate existing count for IP address */
if (0 == found_key->count)
- {
- MHD_PANIC (_("Previously-added IP address had counter of zero\n"));
- }
+ {
+ MHD_PANIC (_ ("Previously-added IP address had counter of zero.\n"));
+ }
/* Remove the node entirely if count reduces to 0 */
if (0 == --found_key->count)
- {
- tdelete (found_key,
- &daemon->per_ip_connection_count,
- &MHD_ip_addr_compare);
- free (found_key);
- }
+ {
+ tdelete (found_key,
+ &daemon->per_ip_connection_count,
+ &MHD_ip_addr_compare);
+ free (found_key);
+ }
MHD_ip_count_unlock (daemon);
}
@@ -431,109 +527,6 @@
#ifdef HTTPS_SUPPORT
/**
- * Callback for receiving data from the socket.
- *
- * @param connection the MHD_Connection structure
- * @param other where to write received data to
- * @param i maximum size of other (in bytes)
- * @return number of bytes actually received
- */
-static ssize_t
-recv_tls_adapter (struct MHD_Connection *connection,
- void *other,
- size_t i)
-{
- ssize_t res;
-
- if (i > SSIZE_MAX)
- i = SSIZE_MAX;
-
- res = gnutls_record_recv (connection->tls_session,
- other,
- i);
- if ( (GNUTLS_E_AGAIN == res) ||
- (GNUTLS_E_INTERRUPTED == res) )
- {
- MHD_socket_set_error_ (MHD_SCKT_EINTR_);
-#ifdef EPOLL_SUPPORT
- if (GNUTLS_E_AGAIN == res)
- connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
-#endif
- return -1;
- }
- if (res < 0)
- {
- /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
- disrupted); set errno to something caller will interpret
- correctly as a hard error */
- MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
- connection->tls_read_ready = false;
- return res;
- }
-
-#ifdef EPOLL_SUPPORT
- /* If data not available to fill whole buffer - socket is not read ready anymore. */
- if (i > (size_t)res)
- connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
-#endif /* EPOLL_SUPPORT */
-
- /* Check whether TLS buffers still have some unread data. */
- connection->tls_read_ready = ( ((size_t)res == i) &&
- (0 != gnutls_record_check_pending (connection->tls_session)) );
- return res;
-}
-
-
-/**
- * Callback for writing data to the socket.
- *
- * @param connection the MHD connection structure
- * @param other data to write
- * @param i number of bytes to write
- * @return actual number of bytes written
- */
-static ssize_t
-send_tls_adapter (struct MHD_Connection *connection,
- const void *other,
- size_t i)
-{
- ssize_t res;
-
- if (i > SSIZE_MAX)
- i = SSIZE_MAX;
-
- res = gnutls_record_send (connection->tls_session,
- other,
- i);
- if ( (GNUTLS_E_AGAIN == res) ||
- (GNUTLS_E_INTERRUPTED == res) )
- {
- MHD_socket_set_error_ (MHD_SCKT_EINTR_);
-#ifdef EPOLL_SUPPORT
- if (GNUTLS_E_AGAIN == res)
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif
- return -1;
- }
- if (res < 0)
- {
- /* some other GNUTLS error, should set 'errno'; as we do not
- really understand the error (not listed in GnuTLS
- documentation explicitly), we set 'errno' to something that
- will cause the connection to fail. */
- MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
- return -1;
- }
-#ifdef EPOLL_SUPPORT
- /* If NOT all available data was sent - socket is not write ready anymore. */
- if (i > (size_t)res)
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif /* EPOLL_SUPPORT */
- return res;
-}
-
-
-/**
* Read and setup our certificate and key.
*
* @param daemon handle to daemon to initialize
@@ -548,78 +541,115 @@
#if GNUTLS_VERSION_MAJOR >= 3
if (NULL != daemon->cert_callback)
- {
- gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
- daemon->cert_callback);
- }
+ {
+ gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
+ daemon->cert_callback);
+ }
#endif
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ else if (NULL != daemon->cert_callback2)
+ {
+ gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
+ daemon->cert_callback2);
+ }
+#endif
+
if (NULL != daemon->https_mem_trust)
+ {
+ size_t paramlen;
+ paramlen = strlen (daemon->https_mem_trust);
+ if (UINT_MAX < paramlen)
{
- cert.data = (unsigned char *) daemon->https_mem_trust;
- cert.size = strlen (daemon->https_mem_trust);
- if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
- &cert,
- GNUTLS_X509_FMT_PEM) < 0)
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG(daemon,
- "Bad trust certificate format\n");
+ MHD_DLOG (daemon,
+ _ ("Too long trust certificate.\n"));
#endif
- return -1;
- }
+ return -1;
}
-
- if (daemon->have_dhparams)
+ cert.data = (unsigned char *) daemon->https_mem_trust;
+ cert.size = (unsigned int) paramlen;
+ if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
+ &cert,
+ GNUTLS_X509_FMT_PEM) < 0)
{
- gnutls_certificate_set_dh_params (daemon->x509_cred,
- daemon->https_mem_dhparams);
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Bad trust certificate format.\n"));
+#endif
+ return -1;
}
+ }
+
+ if (daemon->have_dhparams)
+ {
+ gnutls_certificate_set_dh_params (daemon->x509_cred,
+ daemon->https_mem_dhparams);
+ }
/* certificate & key loaded from memory */
if ( (NULL != daemon->https_mem_cert) &&
(NULL != daemon->https_mem_key) )
+ {
+ size_t param1len;
+ size_t param2len;
+
+ param1len = strlen (daemon->https_mem_key);
+ param2len = strlen (daemon->https_mem_cert);
+ if ( (UINT_MAX < param1len) ||
+ (UINT_MAX < param2len) )
{
- key.data = (unsigned char *) daemon->https_mem_key;
- key.size = strlen (daemon->https_mem_key);
- cert.data = (unsigned char *) daemon->https_mem_cert;
- cert.size = strlen (daemon->https_mem_cert);
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Too long key or certificate.\n"));
+#endif
+ return -1;
+ }
+ key.data = (unsigned char *) daemon->https_mem_key;
+ key.size = (unsigned int) param1len;
+ cert.data = (unsigned char *) daemon->https_mem_cert;
+ cert.size = (unsigned int) param2len;
- if (NULL != daemon->https_key_password) {
+ if (NULL != daemon->https_key_password)
+ {
#if GNUTLS_VERSION_NUMBER >= 0x030111
- ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
- &cert,
- &key,
- GNUTLS_X509_FMT_PEM,
- daemon->https_key_password,
- 0);
+ ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
+ &cert,
+ &key,
+ GNUTLS_X509_FMT_PEM,
+ daemon->https_key_password,
+ 0);
#else
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to setup x509 certificate/key: pre 3.X.X version " \
- "of GnuTLS does not support setting key password"));
+ MHD_DLOG (daemon,
+ _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \
+ "of GnuTLS does not support setting key password.\n"));
#endif
- return -1;
+ return -1;
#endif
- }
- else
- ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
- &cert,
- &key,
- GNUTLS_X509_FMT_PEM);
+ }
+ else
+ ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
+ &cert,
+ &key,
+ GNUTLS_X509_FMT_PEM);
#ifdef HAVE_MESSAGES
- if (0 != ret)
- MHD_DLOG (daemon,
- "GnuTLS failed to setup x509 certificate/key: %s\n",
- gnutls_strerror (ret));
+ if (0 != ret)
+ MHD_DLOG (daemon,
+ _ ("GnuTLS failed to setup x509 certificate/key: %s\n"),
+ gnutls_strerror (ret));
#endif
- return ret;
- }
+ return ret;
+ }
#if GNUTLS_VERSION_MAJOR >= 3
if (NULL != daemon->cert_callback)
return 0;
#endif
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ else if (NULL != daemon->cert_callback2)
+ return 0;
+#endif
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- "You need to specify a certificate and key location\n");
+ _ ("You need to specify a certificate and key location.\n"));
#endif
return -1;
}
@@ -635,21 +665,28 @@
MHD_TLS_init (struct MHD_Daemon *daemon)
{
switch (daemon->cred_type)
- {
- case GNUTLS_CRD_CERTIFICATE:
- if (0 !=
- gnutls_certificate_allocate_credentials (&daemon->x509_cred))
- return GNUTLS_E_MEMORY_ERROR;
- return MHD_init_daemon_certificate (daemon);
- default:
+ {
+ case GNUTLS_CRD_CERTIFICATE:
+ if (0 !=
+ gnutls_certificate_allocate_credentials (&daemon->x509_cred))
+ return GNUTLS_E_MEMORY_ERROR;
+ return MHD_init_daemon_certificate (daemon);
+ case GNUTLS_CRD_PSK:
+ if (0 !=
+ gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
+ return GNUTLS_E_MEMORY_ERROR;
+ return 0;
+ default:
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error: invalid credentials type %d specified.\n"),
- daemon->cred_type);
+ MHD_DLOG (daemon,
+ _ ("Error: invalid credentials type %d specified.\n"),
+ daemon->cred_type);
#endif
- return -1;
- }
+ return -1;
+ }
}
+
+
#endif /* HTTPS_SUPPORT */
@@ -662,6 +699,16 @@
* before calling this function. FD_SETSIZE is assumed
* to be platform's default.
*
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'.
+ * In the latter case, it will only add the single 'epoll' file
+ * descriptor used by MHD to the sets.
+ * It's necessary to use #MHD_get_timeout() in combination with
+ * this function.
+ *
+ * This function must be called only for daemon started
+ * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
+ *
* @param daemon daemon to get sets from
* @param read_fd_set read set
* @param write_fd_set write set
@@ -674,12 +721,12 @@
* fit fd_set.
* @ingroup event
*/
-int
+enum MHD_Result
MHD_get_fdset (struct MHD_Daemon *daemon,
fd_set *read_fd_set,
fd_set *write_fd_set,
- fd_set *except_fd_set,
- MHD_socket *max_fd)
+ fd_set *except_fd_set,
+ MHD_socket *max_fd)
{
return MHD_get_fdset2 (daemon,
read_fd_set,
@@ -718,55 +765,55 @@
/* Do not add to 'es' only if socket is closed
* or not used anymore. */
if (MHD_INVALID_SOCKET != conn_sckt)
- {
- if ( (urh->in_buffer_used < urh->in_buffer_size) &&
- (! MHD_add_to_fd_set_ (conn_sckt,
- rs,
- max_fd,
- fd_setsize)) )
- res = false;
- if ( (0 != urh->out_buffer_used) &&
- (! MHD_add_to_fd_set_ (conn_sckt,
- ws,
- max_fd,
- fd_setsize)) )
- res = false;
- /* Do not monitor again for errors if error was detected before as
- * error state is remembered. */
- if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
- ((0 != urh->in_buffer_size) ||
- (0 != urh->out_buffer_size) ||
- (0 != urh->out_buffer_used)))
- MHD_add_to_fd_set_ (conn_sckt,
- es,
- max_fd,
- fd_setsize);
- }
+ {
+ if ( (urh->in_buffer_used < urh->in_buffer_size) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->out_buffer_used) &&
+ (! MHD_add_to_fd_set_ (conn_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->out_buffer_used)))
+ MHD_add_to_fd_set_ (conn_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
if (MHD_INVALID_SOCKET != mhd_sckt)
- {
- if ( (urh->out_buffer_used < urh->out_buffer_size) &&
- (! MHD_add_to_fd_set_ (mhd_sckt,
- rs,
- max_fd,
- fd_setsize)) )
- res = false;
- if ( (0 != urh->in_buffer_used) &&
- (! MHD_add_to_fd_set_ (mhd_sckt,
- ws,
- max_fd,
- fd_setsize)) )
- res = false;
- /* Do not monitor again for errors if error was detected before as
- * error state is remembered. */
- if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
- ((0 != urh->out_buffer_size) ||
- (0 != urh->in_buffer_size) ||
- (0 != urh->in_buffer_used)))
- MHD_add_to_fd_set_ (mhd_sckt,
- es,
- max_fd,
- fd_setsize);
- }
+ {
+ if ( (urh->out_buffer_used < urh->out_buffer_size) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ rs,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ if ( (0 != urh->in_buffer_used) &&
+ (! MHD_add_to_fd_set_ (mhd_sckt,
+ ws,
+ max_fd,
+ fd_setsize)) )
+ res = false;
+ /* Do not monitor again for errors if error was detected before as
+ * error state is remembered. */
+ if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
+ ((0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_size) ||
+ (0 != urh->in_buffer_used)))
+ MHD_add_to_fd_set_ (mhd_sckt,
+ es,
+ max_fd,
+ fd_setsize);
+ }
return res;
}
@@ -795,25 +842,26 @@
urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
if (MHD_INVALID_SOCKET != conn_sckt)
- {
- if (FD_ISSET (conn_sckt, rs))
- urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
- if (FD_ISSET (conn_sckt, ws))
- urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
- if (FD_ISSET (conn_sckt, es))
- urh->app.celi |= MHD_EPOLL_STATE_ERROR;
- }
+ {
+ if (FD_ISSET (conn_sckt, rs))
+ urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (conn_sckt, ws))
+ urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (conn_sckt, es))
+ urh->app.celi |= MHD_EPOLL_STATE_ERROR;
+ }
if ((MHD_INVALID_SOCKET != mhd_sckt))
- {
- if (FD_ISSET (mhd_sckt, rs))
- urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
- if (FD_ISSET (mhd_sckt, ws))
- urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
- if (FD_ISSET (mhd_sckt, es))
- urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
- }
+ {
+ if (FD_ISSET (mhd_sckt, rs))
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ if (FD_ISSET (mhd_sckt, ws))
+ urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
+ if (FD_ISSET (mhd_sckt, es))
+ urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
+ }
}
+
#ifdef HAVE_POLL
/**
@@ -825,8 +873,8 @@
* @param p pollfd array to update
*/
static void
-urh_update_pollfd(struct MHD_UpgradeResponseHandle *urh,
- struct pollfd p[2])
+urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
{
p[0].events = 0;
p[1].events = 0;
@@ -866,12 +914,13 @@
* @param p pollfd array to set
*/
static void
-urh_to_pollfd(struct MHD_UpgradeResponseHandle *urh,
- struct pollfd p[2])
+urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
{
p[0].fd = urh->connection->socket_fd;
p[1].fd = urh->mhd.socket;
- urh_update_pollfd(urh, p);
+ urh_update_pollfd (urh,
+ p);
}
@@ -881,8 +930,8 @@
* @param p 'poll()' processed pollfd.
*/
static void
-urh_from_pollfd(struct MHD_UpgradeResponseHandle *urh,
- struct pollfd p[2])
+urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
+ struct pollfd p[2])
{
/* Reset read/write ready, preserve error state. */
urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
@@ -905,6 +954,8 @@
if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
}
+
+
#endif /* HAVE_POLL */
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -923,7 +974,7 @@
* fit fd_set.
* @ingroup event
*/
-static int
+static enum MHD_Result
internal_get_fdset2 (struct MHD_Daemon *daemon,
fd_set *read_fd_set,
fd_set *write_fd_set,
@@ -934,7 +985,7 @@
{
struct MHD_Connection *pos;
struct MHD_Connection *posn;
- int result = MHD_YES;
+ enum MHD_Result result = MHD_YES;
MHD_socket ls;
if (daemon->shutdown)
@@ -954,85 +1005,85 @@
* or INFO_WRITE sockets will not fit 'except_fd_set'. */
/* Start from oldest connections. Make sense for W32 FDSETs. */
for (pos = daemon->connections_tail; NULL != pos; pos = posn)
- {
- posn = pos->prev;
+ {
+ posn = pos->prev;
- switch (pos->event_loop_info)
- {
- case MHD_EVENT_LOOP_INFO_READ:
- if (! MHD_add_to_fd_set_ (pos->socket_fd,
- read_fd_set,
- max_fd,
- fd_setsize))
- result = MHD_NO;
+ switch (pos->event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
#ifdef MHD_POSIX_SOCKETS
- MHD_add_to_fd_set_ (pos->socket_fd,
- except_fd_set,
- max_fd,
- fd_setsize);
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
#endif /* MHD_POSIX_SOCKETS */
- break;
- case MHD_EVENT_LOOP_INFO_WRITE:
- if (! MHD_add_to_fd_set_ (pos->socket_fd,
- write_fd_set,
- max_fd,
- fd_setsize))
- result = MHD_NO;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if (! MHD_add_to_fd_set_ (pos->socket_fd,
+ write_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
#ifdef MHD_POSIX_SOCKETS
- MHD_add_to_fd_set_ (pos->socket_fd,
- except_fd_set,
- max_fd,
- fd_setsize);
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
#endif /* MHD_POSIX_SOCKETS */
- break;
- case MHD_EVENT_LOOP_INFO_BLOCK:
- if ( (NULL == except_fd_set) ||
- ! MHD_add_to_fd_set_ (pos->socket_fd,
- except_fd_set,
- max_fd,
- fd_setsize))
- result = MHD_NO;
- break;
- case MHD_EVENT_LOOP_INFO_CLEANUP:
- /* this should never happen */
- break;
- }
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ if ( (NULL == except_fd_set) ||
+ ! MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* this should never happen */
+ break;
}
+ }
#ifdef MHD_WINSOCK_SOCKETS
/* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
* only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
* not be pushed out. */
for (pos = daemon->connections_tail; NULL != pos; pos = posn)
- {
- posn = pos->prev;
- MHD_add_to_fd_set_ (pos->socket_fd,
- except_fd_set,
- max_fd,
- fd_setsize);
- }
+ {
+ posn = pos->prev;
+ MHD_add_to_fd_set_ (pos->socket_fd,
+ except_fd_set,
+ max_fd,
+ fd_setsize);
+ }
#endif /* MHD_WINSOCK_SOCKETS */
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
{
struct MHD_UpgradeResponseHandle *urh;
for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
- {
- if (MHD_NO ==
- urh_to_fdset (urh,
- read_fd_set,
- write_fd_set,
- except_fd_set,
- max_fd,
- fd_setsize))
- result = MHD_NO;
- }
+ {
+ if (MHD_NO ==
+ urh_to_fdset (urh,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set,
+ max_fd,
+ fd_setsize))
+ result = MHD_NO;
+ }
}
#endif
-#if DEBUG_CONNECT
+#if _MHD_DEBUG_CONNECT
#ifdef HAVE_MESSAGES
if (NULL != max_fd)
MHD_DLOG (daemon,
- _("Maximum socket in select set: %d\n"),
+ _ ("Maximum socket in select set: %d\n"),
*max_fd);
#endif
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -1044,9 +1095,17 @@
* Obtain the `select()` sets for this daemon.
* Daemon's FDs will be added to fd_sets. To get only
* daemon FDs in fd_sets, call FD_ZERO for each fd_set
- * before calling this function. Passing custom FD_SETSIZE
- * as @a fd_setsize allow usage of larger/smaller than
- * platform's default fd_sets.
+ * before calling this function.
+ *
+ * Passing custom FD_SETSIZE as @a fd_setsize allow usage of
+ * larger/smaller than platform's default fd_sets.
+ *
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'.
+ * In the latter case, it will only add the single 'epoll' file
+ * descriptor used by MHD to the sets.
+ * It's necessary to use #MHD_get_timeout() in combination with
+ * this function.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -1064,13 +1123,13 @@
* fit fd_set.
* @ingroup event
*/
-int
+enum MHD_Result
MHD_get_fdset2 (struct MHD_Daemon *daemon,
- fd_set *read_fd_set,
- fd_set *write_fd_set,
- fd_set *except_fd_set,
- MHD_socket *max_fd,
- unsigned int fd_setsize)
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *except_fd_set,
+ MHD_socket *max_fd,
+ unsigned int fd_setsize)
{
fd_set es;
@@ -1082,38 +1141,38 @@
return MHD_NO;
if (NULL == except_fd_set)
- { /* Workaround to maintain backward compatibility. */
+ { /* Workaround to maintain backward compatibility. */
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD_get_fdset2() called with except_fd_set "
- "set to NULL. Such behavior is unsupported.\n"));
+ MHD_DLOG (daemon,
+ _ ("MHD_get_fdset2() called with except_fd_set "
+ "set to NULL. Such behavior is unsupported.\n"));
#endif
- FD_ZERO (&es);
- except_fd_set = &es;
- }
+ FD_ZERO (&es);
+ except_fd_set = &es;
+ }
#ifdef EPOLL_SUPPORT
if (0 != (daemon->options & MHD_USE_EPOLL))
- {
- if (daemon->shutdown)
- return MHD_NO;
+ {
+ if (daemon->shutdown)
+ return MHD_NO;
- /* we're in epoll mode, use the epoll FD as a stand-in for
- the entire event set */
+ /* we're in epoll mode, use the epoll FD as a stand-in for
+ the entire event set */
- return MHD_add_to_fd_set_ (daemon->epoll_fd,
- read_fd_set,
- max_fd,
- fd_setsize) ? MHD_YES : MHD_NO;
- }
+ return MHD_add_to_fd_set_ (daemon->epoll_fd,
+ read_fd_set,
+ max_fd,
+ fd_setsize) ? MHD_YES : MHD_NO;
+ }
#endif
return internal_get_fdset2 (daemon,
- read_fd_set,
+ read_fd_set,
write_fd_set,
- except_fd_set,
+ except_fd_set,
max_fd,
- fd_setsize);
+ fd_setsize);
}
@@ -1130,13 +1189,13 @@
* #MHD_NO if a serious error was encountered and the
* connection is to be closed.
*/
-static int
+static enum MHD_Result
call_handlers (struct MHD_Connection *con,
bool read_ready,
bool write_ready,
bool force_close)
{
- int ret;
+ enum MHD_Result ret;
bool states_info_processed = false;
/* Fast track flag */
bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
@@ -1145,40 +1204,40 @@
if (con->tls_read_ready)
read_ready = true;
#endif /* HTTPS_SUPPORT */
- if (!force_close)
+ if (! force_close)
+ {
+ if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
+ read_ready)
{
- if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
- read_ready)
- {
- con->read_handler (con);
- ret = con->idle_handler (con);
- states_info_processed = true;
- }
- /* No need to check value of 'ret' here as closed connection
- * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
- if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
- write_ready)
- {
- con->write_handler (con);
- ret = con->idle_handler (con);
- states_info_processed = true;
- }
+ MHD_connection_handle_read (con);
+ ret = MHD_connection_handle_idle (con);
+ states_info_processed = true;
+ }
+ /* No need to check value of 'ret' here as closed connection
+ * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
+ if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
+ write_ready)
+ {
+ MHD_connection_handle_write (con);
+ ret = MHD_connection_handle_idle (con);
+ states_info_processed = true;
}
+ }
else
- {
- MHD_connection_close_ (con,
- MHD_REQUEST_TERMINATED_WITH_ERROR);
- return con->idle_handler (con);
- }
+ {
+ MHD_connection_close_ (con,
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+ return MHD_connection_handle_idle (con);
+ }
- if (!states_info_processed)
- { /* Connection is not read or write ready, but external conditions
+ if (! states_info_processed)
+ { /* Connection is not read or write ready, but external conditions
* may be changed and need to be processed. */
- ret = con->idle_handler (con);
- }
+ ret = MHD_connection_handle_idle (con);
+ }
/* Fast track for fast connections. */
/* If full request was read by single read_handler() invocation
- and headers were completely prepared by single idle_handler()
+ and headers were completely prepared by single MHD_connection_handle_idle()
then try not to wait for next sockets polling and send response
immediately.
As writeability of socket was not checked and it may have
@@ -1187,23 +1246,23 @@
/* No need to check 'ret' as connection is always in
* MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
else if (on_fasttrack && con->sk_nonblck)
+ {
+ if (MHD_CONNECTION_HEADERS_SENDING == con->state)
{
- if (MHD_CONNECTION_HEADERS_SENDING == con->state)
- {
- con->write_handler (con);
- /* Always call 'idle_handler()' after each read/write. */
- ret = con->idle_handler (con);
- }
- /* If all headers were sent by single write_handler() and
- * response body is prepared by single idle_handler()
- * call - continue. */
- if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
- (MHD_CONNECTION_CHUNKED_BODY_READY == con->state))
- {
- con->write_handler (con);
- ret = con->idle_handler (con);
- }
+ MHD_connection_handle_write (con);
+ /* Always call 'MHD_connection_handle_idle()' after each read/write. */
+ ret = MHD_connection_handle_idle (con);
+ }
+ /* If all headers were sent by single write_handler() and
+ * response body is prepared by single MHD_connection_handle_idle()
+ * call - continue. */
+ if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
+ (MHD_CONNECTION_CHUNKED_BODY_READY == con->state))
+ {
+ MHD_connection_handle_write (con);
+ ret = MHD_connection_handle_idle (con);
}
+ }
/* All connection's data and states are processed for this turn.
* If connection already has more data to be processed - use
@@ -1212,18 +1271,18 @@
* connections are processed individually. */
/* Note: no need to check for read buffer availability for
* TLS read-ready connection in 'read info' state as connection
- * without space in read buffer will be market as 'info block'. */
- if ( (!con->daemon->data_already_pending) &&
+ * without space in read buffer will be marked as 'info block'. */
+ if ( (! con->daemon->data_already_pending) &&
(0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
- {
- if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
- con->daemon->data_already_pending = true;
+ {
+ if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
+ con->daemon->data_already_pending = true;
#ifdef HTTPS_SUPPORT
- else if ( (con->tls_read_ready) &&
- (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
- con->daemon->data_already_pending = true;
+ else if ( (con->tls_read_ready) &&
+ (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
+ con->daemon->data_already_pending = true;
#endif /* HTTPS_SUPPORT */
- }
+ }
return ret;
}
@@ -1259,14 +1318,16 @@
connection->urh = NULL;
free (urh);
}
+
+
#endif /* UPGRADE_SUPPORT */
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
/**
* Performs bi-directional forwarding on upgraded HTTPS connections
- * based on the readyness state stored in the @a urh handle.
- * @remark To be called only from thread that process
+ * based on the readiness state stored in the @a urh handle.
+ * @remark To be called only from thread that processes
* connection's recv(), send() and response.
*
* @param urh handle to process
@@ -1278,64 +1339,70 @@
* pointers to 'connection' and 'daemon' are not changed
* during this processing, so no need to chain dereference
* each time. */
- struct MHD_Connection * const connection = urh->connection;
- struct MHD_Daemon * const daemon = connection->daemon;
+ struct MHD_Connection *const connection = urh->connection;
+ struct MHD_Daemon *const daemon = connection->daemon;
/* Prevent data races: use same value of 'was_closed' throughout
* this function. If 'was_closed' changed externally in the middle
* of processing - it will be processed on next iteration. */
bool was_closed;
+
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (connection->pid) );
+#endif /* MHD_USE_THREADS */
if (daemon->shutdown)
- {
- /* Daemon shutting down, application will not receive any more data. */
+ {
+ /* Daemon shutting down, application will not receive any more data. */
#ifdef HAVE_MESSAGES
- if (! urh->was_closed)
- {
- MHD_DLOG (daemon,
- _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
- }
-#endif
- urh->was_closed = true;
+ if (! urh->was_closed)
+ {
+ MHD_DLOG (daemon,
+ _ (
+ "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
}
+#endif
+ urh->was_closed = true;
+ }
was_closed = urh->was_closed;
if (was_closed)
+ {
+ /* Application was closed connections: no more data
+ * can be forwarded to application socket. */
+ if (0 < urh->in_buffer_used)
{
- /* Application was closed connections: no more data
- * can be forwarded to application socket. */
- if (0 < urh->in_buffer_used)
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
- " bytes of data received from remote side: application shut down socket\n"),
- (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
+ MHD_DLOG (daemon,
+ _ ("Failed to forward to application "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from remote side: application shut down socket.\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
#endif
- }
- /* If application signaled MHD about socket closure then
- * check for any pending data even if socket is not marked
- * as 'ready' (signal may arrive after poll()/select()).
- * Socketpair for forwarding is always in non-blocking mode
- * so no risk that recv() will block the thread. */
- if (0 != urh->out_buffer_size)
- urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
- /* Discard any data received form remote. */
- urh->in_buffer_used = 0;
- /* Do not try to push data to application. */
- urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- /* Reading from remote client is not required anymore. */
- urh->in_buffer_size = 0;
- urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
- connection->tls_read_ready = false;
}
+ /* If application signaled MHD about socket closure then
+ * check for any pending data even if socket is not marked
+ * as 'ready' (signal may arrive after poll()/select()).
+ * Socketpair for forwarding is always in non-blocking mode
+ * so no risk that recv() will block the thread. */
+ if (0 != urh->out_buffer_size)
+ urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
+ /* Discard any data received form remote. */
+ urh->in_buffer_used = 0;
+ /* Do not try to push data to application. */
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Reading from remote client is not required anymore. */
+ urh->in_buffer_size = 0;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ connection->tls_read_ready = false;
+ }
- /* On some platforms (W32, possibly Darwin) failed send() (send() will always
- * fail after remote disconnect was detected) may discard data in system
- * buffers received by system but not yet read by recv().
- * So, before trying send() on any socket, recv() must be performed at first
- * otherwise last part of incoming data may be lost. */
-
- /* If disconnect or error was detected - try to read from socket
- * to dry data possibly pending is system buffers. */
+ /* On some platforms (W32, possibly Darwin) failed send() (send() will
+ * always fail after remote disconnect was detected) may discard data in
+ * system buffers received by system but not yet read by recv(). So, before
+ * trying send() on any socket, recv() must be performed at first otherwise
+ * last part of incoming data may be lost. If disconnect or error was
+ * detected - try to read from socket to dry data possibly pending is system
+ * buffers. */
if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
@@ -1347,237 +1414,241 @@
if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
(connection->tls_read_ready) ) &&
(urh->in_buffer_used < urh->in_buffer_size) )
- {
- ssize_t res;
- size_t buf_size;
-
- buf_size = urh->in_buffer_size - urh->in_buffer_used;
- if (buf_size > SSIZE_MAX)
- buf_size = SSIZE_MAX;
+ {
+ ssize_t res;
+ size_t buf_size;
- connection->tls_read_ready = false;
- res = gnutls_record_recv (connection->tls_session,
- &urh->in_buffer[urh->in_buffer_used],
- buf_size);
- if (0 >= res)
- {
- if (GNUTLS_E_INTERRUPTED != res)
- {
- urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
- if (GNUTLS_E_AGAIN != res)
- {
- /* Unrecoverable error on socket was detected or
- * socket was disconnected/shut down. */
- /* Stop trying to read from this TLS socket. */
- urh->in_buffer_size = 0;
- }
- }
- }
- else /* 0 < res */
- {
- urh->in_buffer_used += res;
- if (buf_size > (size_t)res)
- urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
- else if (0 < gnutls_record_check_pending (connection->tls_session))
- connection->tls_read_ready = true;
- }
- if (MHD_EPOLL_STATE_ERROR ==
- ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
+ buf_size = urh->in_buffer_size - urh->in_buffer_used;
+ if (buf_size > SSIZE_MAX)
+ buf_size = SSIZE_MAX;
+
+ connection->tls_read_ready = false;
+ res = gnutls_record_recv (connection->tls_session,
+ &urh->in_buffer[urh->in_buffer_used],
+ buf_size);
+ if (0 >= res)
+ {
+ if (GNUTLS_E_INTERRUPTED != res)
+ {
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ if (GNUTLS_E_AGAIN != res)
{
- /* Unrecoverable error on socket was detected and all
- * pending data was read from system buffers. */
+ /* Unrecoverable error on socket was detected or
+ * socket was disconnected/shut down. */
/* Stop trying to read from this TLS socket. */
urh->in_buffer_size = 0;
}
+ }
+ }
+ else /* 0 < res */
+ {
+ urh->in_buffer_used += res;
+ if (0 < gnutls_record_check_pending (connection->tls_session))
+ {
+ connection->tls_read_ready = true;
+ }
}
+ if (MHD_EPOLL_STATE_ERROR ==
+ ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was read from system buffers. */
+ /* Stop trying to read from this TLS socket. */
+ urh->in_buffer_size = 0;
+ }
+ }
/*
* handle reading from application
*/
if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
(urh->out_buffer_used < urh->out_buffer_size) )
- {
- ssize_t res;
- size_t buf_size;
+ {
+ ssize_t res;
+ size_t buf_size;
- buf_size = urh->out_buffer_size - urh->out_buffer_used;
- if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
- buf_size = MHD_SCKT_SEND_MAX_SIZE_;
-
- res = MHD_recv_ (urh->mhd.socket,
- &urh->out_buffer[urh->out_buffer_used],
- buf_size);
- if (0 >= res)
- {
- const int err = MHD_socket_get_error_ ();
- if ((0 == res) ||
- ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
- (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err))))
- {
- urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
- if ((0 == res) ||
- (was_closed) ||
- (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
- (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
- {
- /* Socket disconnect/shutdown was detected;
- * Application signaled about closure of 'upgraded' socket;
- * or persistent / unrecoverable error. */
- /* Do not try to pull more data from application. */
- urh->out_buffer_size = 0;
- }
- }
- }
- else /* 0 < res */
- {
- urh->out_buffer_used += res;
- if (buf_size > (size_t)res)
- urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
- }
- if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
- ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
- (was_closed) ) )
- {
- /* Unrecoverable error on socket was detected and all
- * pending data was read from system buffers. */
+ buf_size = urh->out_buffer_size - urh->out_buffer_used;
+ if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
+ buf_size = MHD_SCKT_SEND_MAX_SIZE_;
+
+ res = MHD_recv_ (urh->mhd.socket,
+ &urh->out_buffer[urh->out_buffer_used],
+ buf_size);
+ if (0 >= res)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if ((0 == res) ||
+ ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
+ (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
+ {
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ if ((0 == res) ||
+ (was_closed) ||
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
+ (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
+ {
+ /* Socket disconnect/shutdown was detected;
+ * Application signaled about closure of 'upgraded' socket;
+ * or persistent / unrecoverable error. */
/* Do not try to pull more data from application. */
urh->out_buffer_size = 0;
}
+ }
+ }
+ else /* 0 < res */
+ {
+ urh->out_buffer_used += res;
+ if (buf_size > (size_t) res)
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+ if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
+ ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
+ (was_closed) ) )
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was read from system buffers. */
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
}
+ }
/*
* handle writing to remote HTTPS client
*/
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
(urh->out_buffer_used > 0) )
- {
- ssize_t res;
- size_t data_size;
+ {
+ ssize_t res;
+ size_t data_size;
- data_size = urh->out_buffer_used;
- if (data_size > SSIZE_MAX)
- data_size = SSIZE_MAX;
-
- res = gnutls_record_send (connection->tls_session,
- urh->out_buffer,
- data_size);
- if (0 >= res)
- {
- if (GNUTLS_E_INTERRUPTED != res)
- {
- urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- if (GNUTLS_E_INTERRUPTED != res)
- {
- /* TLS connection shut down or
- * persistent / unrecoverable error. */
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
- " bytes of data received from application: %s\n"),
- (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
- gnutls_strerror(res));
-#endif
- /* Discard any data unsent to remote. */
- urh->out_buffer_used = 0;
- /* Do not try to pull more data from application. */
- urh->out_buffer_size = 0;
- urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
- }
- }
- }
- else /* 0 < res */
- {
- const size_t next_out_buffer_used = urh->out_buffer_used - res;
- if (0 != next_out_buffer_used)
- {
- memmove (urh->out_buffer,
- &urh->out_buffer[res],
- next_out_buffer_used);
- if (data_size > (size_t)res)
- urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- }
- urh->out_buffer_used = next_out_buffer_used;
- }
- if ( (0 == urh->out_buffer_used) &&
- (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
+ data_size = urh->out_buffer_used;
+ if (data_size > SSIZE_MAX)
+ data_size = SSIZE_MAX;
+
+ res = gnutls_record_send (connection->tls_session,
+ urh->out_buffer,
+ data_size);
+ if (0 >= res)
+ {
+ if (GNUTLS_E_INTERRUPTED != res)
+ {
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ if (GNUTLS_E_AGAIN != res)
{
- /* Unrecoverable error on socket was detected and all
- * pending data was sent to remote. */
- /* Do not try to send to remote anymore. */
- urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* TLS connection shut down or
+ * persistent / unrecoverable error. */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to forward to remote client "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from application: %s\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
+ gnutls_strerror (res));
+#endif
+ /* Discard any data unsent to remote. */
+ urh->out_buffer_used = 0;
/* Do not try to pull more data from application. */
urh->out_buffer_size = 0;
urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
}
+ }
+ }
+ else /* 0 < res */
+ {
+ const size_t next_out_buffer_used = urh->out_buffer_used - res;
+ if (0 != next_out_buffer_used)
+ {
+ memmove (urh->out_buffer,
+ &urh->out_buffer[res],
+ next_out_buffer_used);
+ if (data_size > (size_t) res)
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ }
+ urh->out_buffer_used = next_out_buffer_used;
}
+ if ( (0 == urh->out_buffer_used) &&
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
+ {
+ /* Unrecoverable error on socket was detected and all
+ * pending data was sent to remote. */
+ /* Do not try to send to remote anymore. */
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
+ }
/*
* handle writing to application
*/
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
- (urh->in_buffer_used > 0) )
- {
- ssize_t res;
- size_t data_size;
+ (urh->in_buffer_used > 0) )
+ {
+ ssize_t res;
+ size_t data_size;
- data_size = urh->in_buffer_used;
- if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
- data_size = MHD_SCKT_SEND_MAX_SIZE_;
-
- res = MHD_send_ (urh->mhd.socket,
- urh->in_buffer,
- data_size);
- if (0 >= res)
- {
- const int err = MHD_socket_get_error_ ();
- if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
- (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) )
- {
- urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
- {
- /* Socketpair connection shut down or
- * persistent / unrecoverable error. */
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
- " bytes of data received from remote side: %s\n"),
- (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
- MHD_socket_strerr_ (err));
-#endif
- /* Discard any data received form remote. */
- urh->in_buffer_used = 0;
- /* Reading from remote client is not required anymore. */
- urh->in_buffer_size = 0;
- urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
- connection->tls_read_ready = false;
- }
- }
- }
- else /* 0 < res */
- {
- const size_t next_in_buffer_used = urh->in_buffer_used - res;
- if (0 != next_in_buffer_used)
- {
- memmove (urh->in_buffer,
- &urh->in_buffer[res],
- next_in_buffer_used);
- if (data_size > (size_t)res)
- urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- }
- urh->in_buffer_used = next_in_buffer_used;
- }
- if ( (0 == urh->in_buffer_used) &&
- (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
+ data_size = urh->in_buffer_used;
+ if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
+ data_size = MHD_SCKT_SEND_MAX_SIZE_;
+
+ res = MHD_send_ (urh->mhd.socket,
+ urh->in_buffer,
+ data_size);
+ if (0 >= res)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
+ (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
+ {
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
{
- /* Do not try to push data to application. */
- urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Socketpair connection shut down or
+ * persistent / unrecoverable error. */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to forward to application "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from remote side: %s\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
+ MHD_socket_strerr_ (err));
+#endif
+ /* Discard any data received form remote. */
+ urh->in_buffer_used = 0;
/* Reading from remote client is not required anymore. */
urh->in_buffer_size = 0;
urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
connection->tls_read_ready = false;
}
+ }
}
+ else /* 0 < res */
+ {
+ const size_t next_in_buffer_used = urh->in_buffer_used - res;
+ if (0 != next_in_buffer_used)
+ {
+ memmove (urh->in_buffer,
+ &urh->in_buffer[res],
+ next_in_buffer_used);
+ if (data_size > (size_t) res)
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ }
+ urh->in_buffer_used = next_in_buffer_used;
+ }
+ if ( (0 == urh->in_buffer_used) &&
+ (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
+ {
+ /* Do not try to push data to application. */
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Reading from remote client is not required anymore. */
+ urh->in_buffer_size = 0;
+ urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ connection->tls_read_ready = false;
+ }
+ }
/* Check whether data is present in TLS buffers
* and incoming forward buffer have some space. */
@@ -1589,27 +1660,31 @@
if ( (daemon->shutdown) &&
( (0 != urh->out_buffer_size) ||
(0 != urh->out_buffer_used) ) )
- {
- /* Daemon shutting down, discard any remaining forward data. */
+ {
+ /* Daemon shutting down, discard any remaining forward data. */
#ifdef HAVE_MESSAGES
- if (0 < urh->out_buffer_used)
- MHD_DLOG (daemon,
- _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
- " bytes of data received from application: daemon shut down\n"),
- (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
-#endif
- /* Discard any data unsent to remote. */
- urh->out_buffer_used = 0;
- /* Do not try to sent to remote anymore. */
- urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
- /* Do not try to pull more data from application. */
- urh->out_buffer_size = 0;
- urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
- }
+ if (0 < urh->out_buffer_used)
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to forward to remote client "
+ MHD_UNSIGNED_LONG_LONG_PRINTF \
+ " bytes of data received from application: daemon shut down.\n"),
+ (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
+#endif
+ /* Discard any data unsent to remote. */
+ urh->out_buffer_used = 0;
+ /* Do not try to sent to remote anymore. */
+ urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
+ /* Do not try to pull more data from application. */
+ urh->out_buffer_size = 0;
+ urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
+ }
}
-#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
#ifdef UPGRADE_SUPPORT
/**
* Main function of the thread that handles an individual connection
@@ -1626,131 +1701,136 @@
struct MHD_UpgradeResponseHandle *urh = con->urh;
struct MHD_Daemon *daemon = con->daemon;
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (con->pid) );
/* Here, we need to bi-directionally forward
until the application tells us that it is done
with the socket; */
if ( (0 != (daemon->options & MHD_USE_TLS)) &&
- (0 == (daemon->options & MHD_USE_POLL)))
- {
- while ( (0 != urh->in_buffer_size) ||
- (0 != urh->out_buffer_size) ||
- (0 != urh->in_buffer_used) ||
- (0 != urh->out_buffer_used) )
- {
- /* use select */
- fd_set rs;
- fd_set ws;
- fd_set es;
- MHD_socket max_fd;
- int num_ready;
- bool result;
-
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- max_fd = MHD_INVALID_SOCKET;
- result = urh_to_fdset (urh,
- &rs,
- &ws,
- &es,
- &max_fd,
- FD_SETSIZE);
- if (! result)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error preparing select\n"));
-#endif
- break;
- }
- /* FIXME: does this check really needed? */
- if (MHD_INVALID_SOCKET != max_fd)
- {
- struct timeval* tvp;
- struct timeval tv;
- if ( (con->tls_read_ready) &&
- (urh->in_buffer_used < urh->in_buffer_size))
- { /* No need to wait if incoming data is already pending in TLS buffers. */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- tvp = &tv;
- }
- else
- tvp = NULL;
- num_ready = MHD_SYS_select_ (max_fd + 1,
- &rs,
- &ws,
- &es,
- tvp);
- }
- else
- num_ready = 0;
- if (num_ready < 0)
- {
- const int err = MHD_socket_get_error_();
-
- if (MHD_SCKT_ERR_IS_EINTR_(err))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during select (%d): `%s'\n"),
- err,
- MHD_socket_strerr_ (err));
-#endif
- break;
- }
- urh_from_fdset (urh,
- &rs,
- &ws,
- &es);
- process_urh (urh);
+ (0 == (daemon->options & MHD_USE_POLL)))
+ {
+ while ( (0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_used) ||
+ (0 != urh->out_buffer_used) )
+ {
+ /* use select */
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket max_fd;
+ int num_ready;
+ bool result;
+
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ max_fd = MHD_INVALID_SOCKET;
+ result = urh_to_fdset (urh,
+ &rs,
+ &ws,
+ &es,
+ &max_fd,
+ FD_SETSIZE);
+ if (! result)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error preparing select.\n"));
+#endif
+ break;
+ }
+ /* FIXME: does this check really needed? */
+ if (MHD_INVALID_SOCKET != max_fd)
+ {
+ struct timeval*tvp;
+ struct timeval tv;
+ if (((con->tls_read_ready) &&
+ (urh->in_buffer_used < urh->in_buffer_size)) ||
+ (daemon->shutdown))
+ { /* No need to wait if incoming data is already pending in TLS buffers. */
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ tvp = &tv;
}
+ else
+ tvp = NULL;
+ num_ready = MHD_SYS_select_ (max_fd + 1,
+ &rs,
+ &ws,
+ &es,
+ tvp);
+ }
+ else
+ num_ready = 0;
+ if (num_ready < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ urh_from_fdset (urh,
+ &rs,
+ &ws,
+ &es);
+ process_urh (urh);
}
+ }
#ifdef HAVE_POLL
else if (0 != (daemon->options & MHD_USE_TLS))
- {
- /* use poll() */
- struct pollfd p[2];
- memset (p,
- 0,
- sizeof (p));
- p[0].fd = urh->connection->socket_fd;
- p[1].fd = urh->mhd.socket;
-
- while ( (0 != urh->in_buffer_size) ||
- (0 != urh->out_buffer_size) ||
- (0 != urh->in_buffer_used) ||
- (0 != urh->out_buffer_used) )
- {
- int timeout;
-
- urh_update_pollfd(urh, p);
+ {
+ /* use poll() */
+ struct pollfd p[2];
+ memset (p,
+ 0,
+ sizeof (p));
+ p[0].fd = urh->connection->socket_fd;
+ p[1].fd = urh->mhd.socket;
+
+ while ( (0 != urh->in_buffer_size) ||
+ (0 != urh->out_buffer_size) ||
+ (0 != urh->in_buffer_used) ||
+ (0 != urh->out_buffer_used) )
+ {
+ int timeout;
+
+ urh_update_pollfd (urh, p);
+
+ if (((con->tls_read_ready) &&
+ (urh->in_buffer_used < urh->in_buffer_size)) ||
+ (daemon->shutdown))
+ timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
+ else
+ timeout = -1;
- if ( (con->tls_read_ready) &&
- (urh->in_buffer_used < urh->in_buffer_size))
- timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
- else
- timeout = -1;
+ if (MHD_sys_poll_ (p,
+ 2,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
- if (MHD_sys_poll_ (p,
- 2,
- timeout) < 0)
- {
- const int err = MHD_socket_get_error_ ();
-
- if (MHD_SCKT_ERR_IS_EINTR_ (err))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during poll: `%s'\n"),
- MHD_socket_strerr_ (err));
-#endif
- break;
- }
- urh_from_pollfd(urh, p);
- process_urh (urh);
- }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ urh_from_pollfd (urh,
+ p);
+ process_urh (urh);
}
+ }
/* end POLL */
#endif
/* end HTTPS */
@@ -1760,6 +1840,8 @@
/* Do not set 'urh->clean_ready' yet as 'urh' will be used
* in connection thread for a little while. */
}
+
+
#endif /* UPGRADE_SUPPORT */
@@ -1801,628 +1883,522 @@
const bool use_poll = 0;
#endif /* ! HAVE_POLL */
bool was_suspended = false;
+ MHD_thread_init_ (&(con->pid));
while ( (! daemon->shutdown) &&
- (MHD_CONNECTION_CLOSED != con->state) )
- {
- const time_t timeout = daemon->connection_timeout;
+ (MHD_CONNECTION_CLOSED != con->state) )
+ {
+ const time_t timeout = daemon->connection_timeout;
#ifdef UPGRADE_SUPPORT
- struct MHD_UpgradeResponseHandle * const urh = con->urh;
+ struct MHD_UpgradeResponseHandle *const urh = con->urh;
#else /* ! UPGRADE_SUPPORT */
- static const void * const urh = NULL;
+ static const void *const urh = NULL;
#endif /* ! UPGRADE_SUPPORT */
- if ( (con->suspended) &&
- (NULL == urh) )
+ if ( (con->suspended) &&
+ (NULL == urh) )
+ {
+ /* Connection was suspended, wait for resume. */
+ was_suspended = true;
+ if (! use_poll)
+ {
+ FD_ZERO (&rs);
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ NULL,
+ FD_SETSIZE))
{
- /* Connection was suspended, wait for resume. */
- was_suspended = true;
- if (! use_poll)
- {
- FD_ZERO (&rs);
- if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
- &rs,
- NULL,
- FD_SETSIZE))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Failed to add FD to fd_set\n"));
+ MHD_DLOG (con->daemon,
+ _ ("Failed to add FD to fd_set.\n"));
#endif
- goto exit;
- }
- if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
- &rs,
- NULL,
- NULL,
- NULL))
- {
- const int err = MHD_socket_get_error_();
-
- if (MHD_SCKT_ERR_IS_EINTR_(err))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during select (%d): `%s'\n"),
- err,
- MHD_socket_strerr_ (err));
-#endif
- break;
- }
- }
-#ifdef HAVE_POLL
- else /* use_poll */
- {
- p[0].events = POLLIN;
- p[0].fd = MHD_itc_r_fd_ (daemon->itc);
- p[0].revents = 0;
- if (0 > MHD_sys_poll_ (p,
- 1,
- -1))
- {
- if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during poll: `%s'\n"),
- MHD_socket_last_strerr_ ());
-#endif
- break;
- }
- }
-#endif /* HAVE_POLL */
- MHD_itc_clear_ (daemon->itc);
- continue; /* Check again for resume. */
- } /* End of "suspended" branch. */
+ goto exit;
+ }
+ if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
+ &rs,
+ NULL,
+ NULL,
+ NULL))
+ {
+ const int err = MHD_socket_get_error_ ();
- if (was_suspended)
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
+#endif
+ break;
+ }
+ }
+#ifdef HAVE_POLL
+ else /* use_poll */
+ {
+ p[0].events = POLLIN;
+ p[0].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[0].revents = 0;
+ if (0 > MHD_sys_poll_ (p,
+ 1,
+ -1))
{
- MHD_update_last_activity_ (con); /* Reset timeout timer. */
- /* Process response queued during suspend and update states. */
- MHD_connection_handle_idle (con);
- was_suspended = false;
+ if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ break;
}
+ }
+#endif /* HAVE_POLL */
+ MHD_itc_clear_ (daemon->itc);
+ continue; /* Check again for resume. */
+ } /* End of "suspended" branch. */
+
+ if (was_suspended)
+ {
+ MHD_update_last_activity_ (con); /* Reset timeout timer. */
+ /* Process response queued during suspend and update states. */
+ MHD_connection_handle_idle (con);
+ was_suspended = false;
+ }
- tvp = NULL;
+ tvp = NULL;
- if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
+ if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
#ifdef HTTPS_SUPPORT
- || ( (con->tls_read_ready) &&
- (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
+ || ( (con->tls_read_ready) &&
+ (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
#endif /* HTTPS_SUPPORT */
)
- {
- /* do not block: more data may be inside of TLS buffers waiting or
- * application must provide response data */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- tvp = &tv;
- }
- if ( (NULL == tvp) &&
- (timeout > 0) )
- {
- now = MHD_monotonic_sec_counter();
- if (now - con->last_activity > timeout)
- tv.tv_sec = 0;
- else
- {
- const time_t seconds_left = timeout - (now - con->last_activity);
-#ifndef _WIN32
- tv.tv_sec = seconds_left;
-#else /* _WIN32 */
- if (seconds_left > TIMEVAL_TV_SEC_MAX)
- tv.tv_sec = TIMEVAL_TV_SEC_MAX;
- else
- tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
-#endif /* _WIN32 */
- }
- tv.tv_usec = 0;
- tvp = &tv;
- }
- if (! use_poll)
- {
- /* use select */
- bool err_state = false;
-
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- maxsock = MHD_INVALID_SOCKET;
- switch (con->event_loop_info)
- {
- case MHD_EVENT_LOOP_INFO_READ:
- if (! MHD_add_to_fd_set_ (con->socket_fd,
- &rs,
- &maxsock,
- FD_SETSIZE))
- err_state = true;
- break;
- case MHD_EVENT_LOOP_INFO_WRITE:
- if (! MHD_add_to_fd_set_ (con->socket_fd,
- &ws,
- &maxsock,
- FD_SETSIZE))
- err_state = true;
- break;
- case MHD_EVENT_LOOP_INFO_BLOCK:
- if (! MHD_add_to_fd_set_ (con->socket_fd,
- &es,
- &maxsock,
- FD_SETSIZE))
- err_state = true;
- break;
- case MHD_EVENT_LOOP_INFO_CLEANUP:
- /* how did we get here!? */
- goto exit;
- }
+ {
+ /* do not block: more data may be inside of TLS buffers waiting or
+ * application must provide response data */
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ if ( (NULL == tvp) &&
+ (timeout > 0) )
+ {
+ now = MHD_monotonic_sec_counter ();
+ if (now - con->last_activity > timeout)
+ tv.tv_sec = 0;
+ else
+ {
+ const time_t seconds_left = timeout - (now - con->last_activity);
+#if ! defined(_WIN32) || defined(__CYGWIN__)
+ tv.tv_sec = seconds_left;
+#else /* _WIN32 && !__CYGWIN__ */
+ if (seconds_left > TIMEVAL_TV_SEC_MAX)
+ tv.tv_sec = TIMEVAL_TV_SEC_MAX;
+ else
+ tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
+#endif /* _WIN32 && ! __CYGWIN__ */
+ }
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+ if (! use_poll)
+ {
+ /* use select */
+ bool err_state = false;
+
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ maxsock = MHD_INVALID_SOCKET;
+ switch (con->event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &ws,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ if (! MHD_add_to_fd_set_ (con->socket_fd,
+ &es,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = true;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* how did we get here!? */
+ goto exit;
+ }
#if WINDOWS
- if (MHD_ITC_IS_VALID_(daemon->itc) )
- {
- if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
- &rs,
- &maxsock,
- FD_SETSIZE))
- err_state = 1;
- }
-#endif
- if (err_state)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Failed to add FD to fd_set\n"));
-#endif
- goto exit;
- }
-
- num_ready = MHD_SYS_select_ (maxsock + 1,
- &rs,
- &ws,
- NULL,
- tvp);
- if (num_ready < 0)
- {
- const int err = MHD_socket_get_error_();
-
- if (MHD_SCKT_ERR_IS_EINTR_(err))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during select (%d): `%s'\n"),
- err,
- MHD_socket_strerr_ (err));
+ if (MHD_ITC_IS_VALID_ (daemon->itc) )
+ {
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ err_state = 1;
+ }
+#endif
+ if (err_state)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Failed to add FD to fd_set.\n"));
+#endif
+ goto exit;
+ }
+
+ num_ready = MHD_SYS_select_ (maxsock + 1,
+ &rs,
+ &ws,
+ &es,
+ tvp);
+ if (num_ready < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during select (%d): `%s'\n"),
+ err,
+ MHD_socket_strerr_ (err));
#endif
- break;
- }
+ break;
+ }
#if WINDOWS
- /* Clear ITC before other processing so additional
- * signals will trigger select() again */
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
- (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
- &rs)) )
- MHD_itc_clear_ (daemon->itc);
-#endif
- if (MHD_NO ==
- call_handlers (con,
- FD_ISSET (con->socket_fd,
- &rs),
- FD_ISSET (con->socket_fd,
- &ws),
- FD_ISSET (con->socket_fd,
- &es)) )
- goto exit;
- }
+ /* Clear ITC before other processing so additional
+ * signals will trigger select() again */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
+ &rs)) )
+ MHD_itc_clear_ (daemon->itc);
+#endif
+ if (MHD_NO ==
+ call_handlers (con,
+ FD_ISSET (con->socket_fd,
+ &rs),
+ FD_ISSET (con->socket_fd,
+ &ws),
+ FD_ISSET (con->socket_fd,
+ &es)) )
+ goto exit;
+ }
#ifdef HAVE_POLL
- else
- {
- /* use poll */
- memset (&p,
- 0,
- sizeof (p));
- p[0].fd = con->socket_fd;
- switch (con->event_loop_info)
- {
- case MHD_EVENT_LOOP_INFO_READ:
- p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_WRITE:
- p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_BLOCK:
- p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_CLEANUP:
- /* how did we get here!? */
- goto exit;
- }
+ else
+ {
+ /* use poll */
+ memset (&p,
+ 0,
+ sizeof (p));
+ p[0].fd = con->socket_fd;
+ switch (con->event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* how did we get here!? */
+ goto exit;
+ }
#if WINDOWS
- extra_slot = 0;
- if (MHD_ITC_IS_VALID_(daemon->itc))
- {
- p[1].events |= POLLIN;
- p[1].fd = MHD_itc_r_fd_ (daemon->itc);
- p[1].revents = 0;
- extra_slot = 1;
- }
+ extra_slot = 0;
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[1].events |= POLLIN;
+ p[1].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[1].revents = 0;
+ extra_slot = 1;
+ }
#endif
- if (MHD_sys_poll_ (p,
+ if (MHD_sys_poll_ (p,
#if WINDOWS
- 1 + extra_slot,
+ 1 + extra_slot,
#else
- 1,
+ 1,
#endif
- (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
- {
- if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_))
- continue;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Error during poll: `%s'\n"),
- MHD_socket_last_strerr_ ());
+ (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
+ {
+ if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
+ continue;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (con->daemon,
+ _ ("Error during poll: `%s'\n"),
+ MHD_socket_last_strerr_ ());
#endif
- break;
- }
+ break;
+ }
#if WINDOWS
- /* Clear ITC before other processing so additional
- * signals will trigger poll() again */
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
- (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
- MHD_itc_clear_ (daemon->itc);
-#endif
- if (MHD_NO ==
- call_handlers (con,
- 0 != (p[0].revents & POLLIN),
- 0 != (p[0].revents & POLLOUT),
- 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
- goto exit;
- }
+ /* Clear ITC before other processing so additional
+ * signals will trigger poll() again */
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
+ MHD_itc_clear_ (daemon->itc);
+#endif
+ if (MHD_NO ==
+ call_handlers (con,
+ (0 != (p[0].revents & POLLIN)),
+ (0 != (p[0].revents & POLLOUT)),
+ (0 != (p[0].revents & (POLLERR
+ | MHD_POLL_REVENTS_ERR_DISC))) ))
+ goto exit;
+ }
#endif
#ifdef UPGRADE_SUPPORT
- if (MHD_CONNECTION_UPGRADE == con->state)
- {
- /* Normal HTTP processing is finished,
- * notify application. */
- if ( (NULL != daemon->notify_completed) &&
- (con->client_aware) )
- daemon->notify_completed (daemon->notify_completed_cls,
- con,
- &con->client_context,
- MHD_REQUEST_TERMINATED_COMPLETED_OK);
- con->client_aware = false;
-
- thread_main_connection_upgrade (con);
- /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
-
- /* "Upgraded" data will not be used in this thread from this point. */
- con->urh->clean_ready = true;
- /* If 'urh->was_closed' set to true, connection will be
- * moved immediately to cleanup list. Otherwise connection
- * will stay in suspended list until 'urh' will be marked
- * with 'was_closed' by application. */
- MHD_resume_connection(con);
+ if (MHD_CONNECTION_UPGRADE == con->state)
+ {
+ /* Normal HTTP processing is finished,
+ * notify application. */
+ if ( (NULL != daemon->notify_completed) &&
+ (con->client_aware) )
+ daemon->notify_completed (daemon->notify_completed_cls,
+ con,
+ &con->client_context,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ con->client_aware = false;
+
+ thread_main_connection_upgrade (con);
+ /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
+
+ /* "Upgraded" data will not be used in this thread from this point. */
+ con->urh->clean_ready = true;
+ /* If 'urh->was_closed' set to true, connection will be
+ * moved immediately to cleanup list. Otherwise connection
+ * will stay in suspended list until 'urh' will be marked
+ * with 'was_closed' by application. */
+ MHD_resume_connection (con);
- /* skip usual clean up */
- return (MHD_THRD_RTRN_TYPE_) 0;
- }
-#endif /* UPGRADE_SUPPORT */
+ /* skip usual clean up */
+ return (MHD_THRD_RTRN_TYPE_) 0;
}
- if (MHD_CONNECTION_IN_CLEANUP != con->state)
- {
-#if DEBUG_CLOSE
+#endif /* UPGRADE_SUPPORT */
+ }
+#if _MHD_DEBUG_CLOSE
#ifdef HAVE_MESSAGES
- MHD_DLOG (con->daemon,
- _("Processing thread terminating. Closing connection\n"));
+ MHD_DLOG (con->daemon,
+ _ ("Processing thread terminating. Closing connection.\n"));
#endif
#endif
- if (MHD_CONNECTION_CLOSED != con->state)
- MHD_connection_close_ (con,
- (daemon->shutdown) ?
- MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN:
- MHD_REQUEST_TERMINATED_WITH_ERROR);
- con->idle_handler (con);
- }
+ if (MHD_CONNECTION_CLOSED != con->state)
+ MHD_connection_close_ (con,
+ (daemon->shutdown) ?
+ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
+ MHD_REQUEST_TERMINATED_WITH_ERROR);
+ MHD_connection_handle_idle (con);
exit:
if (NULL != con->response)
- {
- MHD_destroy_response (con->response);
- con->response = NULL;
- }
+ {
+ MHD_destroy_response (con->response);
+ con->response = NULL;
+ }
if (MHD_INVALID_SOCKET != con->socket_fd)
- {
- shutdown (con->socket_fd,
- SHUT_WR);
- /* 'socket_fd' can be used in other thread to signal shutdown.
- * To avoid data races, do not close socket here. Daemon will
- * use more connections only after cleanup anyway. */
- }
+ {
+ shutdown (con->socket_fd,
+ SHUT_WR);
+ /* 'socket_fd' can be used in other thread to signal shutdown.
+ * To avoid data races, do not close socket here. Daemon will
+ * use more connections only after cleanup anyway. */
+ }
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc, "t")) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to signal thread termination via inter-thread communication channel.\n"));
+#endif
+ }
return (MHD_THRD_RTRN_TYPE_) 0;
}
+#endif
+
+
/**
- * Callback for receiving data from the socket.
+ * Free resources associated with all closed connections.
+ * (destroy responses, free buffers, etc.). All closed
+ * connections are kept in the "cleanup" doubly-linked list.
*
- * @param connection the MHD connection structure
- * @param other where to write received data to
- * @param i maximum size of other (in bytes)
- * @return number of bytes actually received
+ * @param daemon daemon to clean up
+ */
+static void
+MHD_cleanup_connections (struct MHD_Daemon *daemon);
+
+#if defined(HTTPS_SUPPORT)
+#if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \
+ defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
+ ! defined(MHD_socket_nosignal_) && \
+ (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
+/**
+ * Older version of GnuTLS do not support suppressing of SIGPIPE signal.
+ * Use push function replacement with suppressing SIGPIPE signal where necessary
+ * and if possible.
+ */
+#define MHD_TLSLIB_NEED_PUSH_FUNC 1
+#endif /* MHD_SEND_SPIPE_SUPPRESS_NEEDED &&
+ MHD_SEND_SPIPE_SUPPRESS_POSSIBLE &&
+ ! MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) &&
+ MSG_NOSIGNAL */
+
+#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
+/**
+ * Data push function replacement with suppressing SIGPIPE signal
+ * for TLS library.
*/
static ssize_t
-recv_param_adapter (struct MHD_Connection *connection,
- void *other,
- size_t i)
+MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
+ const void *data,
+ size_t data_size)
{
- ssize_t ret;
+#if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
+ if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
+ data_size = MHD_SCKT_SEND_MAX_SIZE_;
+#endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
+ return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size);
+}
- if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
- (MHD_CONNECTION_CLOSED == connection->state) )
- {
- MHD_socket_set_error_ (MHD_SCKT_ENOTCONN_);
- return -1;
- }
- if (i > MHD_SCKT_SEND_MAX_SIZE_)
- i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
- ret = MHD_recv_ (connection->socket_fd,
- other,
- i);
-#ifdef EPOLL_SUPPORT
- if (0 > ret)
- {
- /* Got EAGAIN --- no longer read-ready */
- if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
- connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
- }
- else if (i > (size_t)ret)
- connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
-#endif
- return ret;
-}
+#endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
/**
- * Callback for writing data to the socket.
+ * Function called by GNUtls to obtain the PSK for a given session.
*
- * @param connection the MHD connection structure
- * @param other data to write
- * @param i number of bytes to write
- * @return actual number of bytes written
+ * @param session the session to lookup PSK for
+ * @param username username to lookup PSK for
+ * @param[out] key where to write PSK
+ * @return 0 on success, -1 on error
*/
-static ssize_t
-send_param_adapter (struct MHD_Connection *connection,
- const void *other,
- size_t i)
+static int
+psk_gnutls_adapter (gnutls_session_t session,
+ const char *username,
+ gnutls_datum_t *key)
{
- ssize_t ret;
- int err;
-
- if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
- (MHD_CONNECTION_CLOSED == connection->state) )
- {
- MHD_socket_set_error_ (MHD_SCKT_ENOTCONN_);
- return -1;
- }
- if (i > MHD_SCKT_SEND_MAX_SIZE_)
- i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
+ struct MHD_Connection *connection;
+ struct MHD_Daemon *daemon;
+ void *app_psk;
+ size_t app_psk_size;
- if (0 != (connection->daemon->options & MHD_USE_TLS))
- return MHD_send_ (connection->socket_fd,
- other,
- i);
-#if LINUX
- if ( (connection->write_buffer_append_offset ==
- connection->write_buffer_send_offset) &&
- (NULL != connection->response) &&
- (MHD_resp_sender_sendfile == connection->resp_sender) )
- {
- /* can use sendfile */
- int file_fd = connection->response->fd;
- uint64_t left;
- uint64_t offsetu64;
-#ifndef HAVE_SENDFILE64
- off_t offset;
-#else /* HAVE_SENDFILE64 */
- off64_t offset;
-#endif /* HAVE_SENDFILE64 */
- offsetu64 = connection->response_write_position + connection->response->fd_off;
- left = connection->response->total_size - connection->response_write_position;
- ret = 0;
-#ifndef HAVE_SENDFILE64
- if ((uint64_t)OFF_T_MAX < offsetu64)
- MHD_socket_set_error_to_ENOMEM ();
- else
- {
- offset = (off_t) offsetu64;
- ret = sendfile (connection->socket_fd,
- file_fd,
- &offset,
- left);
- }
-#else /* HAVE_SENDFILE64 */
- if ((uint64_t)OFF64_T_MAX < offsetu64)
- MHD_socket_set_error_to_ENOMEM ();
- else
- {
- offset = (off64_t) offsetu64;
- ret = sendfile64 (connection->socket_fd,
- file_fd,
- &offset,
- left);
- }
-#endif /* HAVE_SENDFILE64 */
- if (0 < ret)
- {
- /* write successful */
-#ifdef EPOLL_SUPPORT
- if (left > (uint64_t)ret)
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif /* EPOLL_SUPPORT */
- return ret;
- }
- err = MHD_socket_get_error_();
-#ifdef EPOLL_SUPPORT
- if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) )
- {
- /* EAGAIN --- no longer write-ready */
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
- }
+ connection = gnutls_session_get_ptr (session);
+ if (NULL == connection)
+ {
+#ifdef HAVE_MESSAGES
+ /* Cannot use our logger, we don't even have "daemon" */
+ MHD_PANIC (_ ("Internal server error. This should be impossible.\n"));
+#endif
+ return -1;
+ }
+ daemon = connection->daemon;
+#if GNUTLS_VERSION_MAJOR >= 3
+ if (NULL == daemon->cred_callback)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("PSK not supported by this server.\n"));
+#endif
+ return -1;
+ }
+ if (0 != daemon->cred_callback (daemon->cred_callback_cls,
+ connection,
+ username,
+ &app_psk,
+ &app_psk_size))
+ return -1;
+ if (NULL == (key->data = gnutls_malloc (app_psk_size)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "PSK authentication failed: gnutls_malloc failed to allocate memory.\n"));
+#endif
+ free (app_psk);
+ return -1;
+ }
+ if (UINT_MAX < app_psk_size)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("PSK authentication failed: PSK too long.\n"));
+#endif
+ free (app_psk);
+ return -1;
+ }
+ key->size = (unsigned int) app_psk_size;
+ memcpy (key->data,
+ app_psk,
+ app_psk_size);
+ free (app_psk);
+ return 0;
+#else
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("PSK not supported by this server.\n"));
+#endif
+ return -1;
#endif
- if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
- MHD_SCKT_ERR_IS_EAGAIN_ (err))
- return 0;
- if (MHD_SCKT_ERR_IS_(err,
- MHD_SCKT_EBADF_))
- return -1;
- /* sendfile() failed with EINVAL if mmap()-like operations are not
- supported for FD or other 'unusual' errors occurred, so we should try
- to fall back to 'SEND'; see also this thread for info on
- odd libc/Linux behavior with sendfile:
- http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
- connection->resp_sender = MHD_resp_sender_std;
- }
-#endif
- ret = MHD_send_ (connection->socket_fd,
- other,
- i);
- err = MHD_socket_get_error_();
-#ifdef EPOLL_SUPPORT
- if (0 > ret)
- {
- /* EAGAIN --- no longer write-ready */
- if (MHD_SCKT_ERR_IS_EAGAIN_(err))
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
- }
- else if (i > (size_t)ret)
- connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
-#endif
- /* Handle broken kernel / libc, returning -1 but not setting errno;
- kill connection as that should be safe; reported on mailinglist here:
- http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
- if ( (0 > ret) &&
- (0 == err) )
- MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
- return ret;
}
-/**
- * Free resources associated with all closed connections.
- * (destroy responses, free buffers, etc.). All closed
- * connections are kept in the "cleanup" doubly-linked list.
- *
- * @param daemon daemon to clean up
- */
-static void
-MHD_cleanup_connections (struct MHD_Daemon *daemon);
+#endif /* HTTPS_SUPPORT */
/**
- * Add another client connection to the set of connections
- * managed by MHD. This API is usually not needed (since
- * MHD will accept inbound connections on the server socket).
- * Use this API in special cases, for example if your HTTP
- * server is behind NAT and needs to connect out to the
- * HTTP client.
+ * Do basic preparation work on the new incoming connection.
*
- * The given client socket will be managed (and closed!) by MHD after
- * this call and must no longer be used directly by the application
- * afterwards.
- *
- * Per-IP connection limits are ignored when using this API.
- *
- * @remark To be called only from thread that process
- * daemon's select()/poll()/etc.
+ * This function do all preparation that is possible outside main daemon
+ * thread.
+ * @remark Could be called from any thread.
*
* @param daemon daemon that manages the connection
* @param client_socket socket to manage (MHD will expect
* to receive an HTTP request from this socket next).
* @param addr IP address of the client
* @param addrlen number of bytes in @a addr
- * @param external_add perform additional operations needed due
- * to the application calling us directly
+ * @param external_add indicate that socket has been added externally
* @param non_blck indicate that socket in non-blocking mode
- * @return #MHD_YES on success, #MHD_NO if this daemon could
+ * @param sk_spipe_supprs indicate that the @a client_socket has
+ * set SIGPIPE suppression
+ * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
+ * @return pointer to the connection on success, NULL if this daemon could
* not handle the connection (i.e. malloc failed, etc).
- * The socket will be closed in any case; 'errno' is
+ * The socket will be closed in case of error; 'errno' is
* set to indicate further details about the error.
*/
-static int
-internal_add_connection (struct MHD_Daemon *daemon,
- MHD_socket client_socket,
- const struct sockaddr *addr,
- socklen_t addrlen,
- int external_add,
- bool non_blck)
+static struct MHD_Connection *
+new_connection_prepare_ (struct MHD_Daemon *daemon,
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen,
+ bool external_add,
+ bool non_blck,
+ bool sk_spipe_supprs,
+ enum MHD_tristate sk_is_nonip)
{
struct MHD_Connection *connection;
- unsigned int i;
- int eno;
- struct MHD_Daemon *worker;
-
- if (NULL != daemon->worker_pool)
- {
- /* have a pool, try to find a pool with capacity; we use the
- socket as the initial offset into the pool for load
- balancing */
- for (i=0;i<daemon->worker_pool_size;i++)
- {
- worker = &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
- if (worker->connections < worker->connection_limit)
- return internal_add_connection (worker,
- client_socket,
- addr,
- addrlen,
- external_add,
- non_blck);
- }
- /* all pools are at their connection limit, must refuse */
- MHD_socket_close_chk_ (client_socket);
-#if ENFILE
- errno = ENFILE;
-#endif
- return MHD_NO;
- }
+ int eno = 0;
- if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket,
- NULL)) &&
- (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
- (int) client_socket,
- (int) FD_SETSIZE);
-#endif
- MHD_socket_close_chk_ (client_socket);
-#if EINVAL
- errno = EINVAL;
-#endif
- return MHD_NO;
- }
-
-#ifdef MHD_socket_nosignal_
- if (! MHD_socket_nosignal_ (client_socket))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
- MHD_socket_last_strerr_());
-#endif
-#ifndef MSG_NOSIGNAL
- /* Cannot use socket as it can produce SIGPIPE. */
-#ifdef ENOTSOCK
- errno = ENOTSOCK;
-#endif /* ENOTSOCK */
- return MHD_NO;
-#endif /* ! MSG_NOSIGNAL */
- }
-#endif /* MHD_socket_nosignal_ */
-
-
-#ifdef HAVE_MESSAGES
-#if DEBUG_CONNECT
+#if _MHD_DEBUG_CONNECT
MHD_DLOG (daemon,
- _("Accepted connection on socket %d\n"),
+ _ ("Accepted connection on socket %d.\n"),
client_socket);
#endif
#endif
@@ -2430,164 +2406,350 @@
(MHD_NO == MHD_ip_limit_add (daemon,
addr,
addrlen)) )
- {
- /* above connection limit - reject */
+ {
+ /* above connection limit - reject */
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Server reached connection limit. Closing inbound connection.\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Server reached connection limit. Closing inbound connection.\n"));
#endif
- MHD_socket_close_chk_ (client_socket);
+ MHD_socket_close_chk_ (client_socket);
#if ENFILE
- errno = ENFILE;
+ errno = ENFILE;
#endif
- return MHD_NO;
- }
+ return NULL;
+ }
/* apply connection acceptance policy if present */
if ( (NULL != daemon->apc) &&
(MHD_NO == daemon->apc (daemon->apc_cls,
- addr,
+ addr,
addrlen)) )
- {
-#if DEBUG_CLOSE
+ {
+#if _MHD_DEBUG_CLOSE
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Connection rejected by application. Closing connection.\n"));
+ MHD_DLOG (daemon,
+ _ ("Connection rejected by application. Closing connection.\n"));
#endif
#endif
- MHD_socket_close_chk_ (client_socket);
- MHD_ip_limit_del (daemon,
- addr,
- addrlen);
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
#if EACCESS
- errno = EACCESS;
+ errno = EACCESS;
#endif
- return MHD_NO;
- }
+ return NULL;
+ }
if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
- {
- eno = errno;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Error allocating memory: %s\n",
- MHD_strerror_ (errno));
-#endif
- MHD_socket_close_chk_ (client_socket);
- MHD_ip_limit_del (daemon,
- addr,
- addrlen);
- errno = eno;
- return MHD_NO;
- }
- connection->pool = MHD_pool_create (daemon->pool_size);
- if (NULL == connection->pool)
- {
+ {
+ eno = errno;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error allocating memory: %s\n"),
- MHD_strerror_ (errno));
-#endif
- MHD_socket_close_chk_ (client_socket);
- MHD_ip_limit_del (daemon,
- addr,
- addrlen);
- free (connection);
-#if ENOMEM
- errno = ENOMEM;
+ MHD_DLOG (daemon,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
#endif
- return MHD_NO;
- }
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ errno = eno;
+ return NULL;
+ }
+
+ if (! external_add)
+ {
+ connection->sk_corked = _MHD_OFF;
+ connection->sk_nodelay = _MHD_OFF;
+ }
+ else
+ {
+ connection->sk_corked = _MHD_UNKNOWN;
+ connection->sk_nodelay = _MHD_UNKNOWN;
+ }
connection->connection_timeout = daemon->connection_timeout;
if (NULL == (connection->addr = malloc (addrlen)))
- {
- eno = errno;
+ {
+ eno = errno;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error allocating memory: %s\n"),
- MHD_strerror_ (errno));
+ MHD_DLOG (daemon,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
#endif
- MHD_socket_close_chk_ (client_socket);
- MHD_ip_limit_del (daemon,
- addr,
- addrlen);
- MHD_pool_destroy (connection->pool);
- free (connection);
- errno = eno;
- return MHD_NO;
- }
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection);
+ errno = eno;
+ return NULL;
+ }
memcpy (connection->addr,
addr,
addrlen);
connection->addr_len = addrlen;
connection->socket_fd = client_socket;
connection->sk_nonblck = non_blck;
+ connection->is_nonip = sk_is_nonip;
+ connection->sk_spipe_suppress = sk_spipe_supprs;
connection->daemon = daemon;
- connection->last_activity = MHD_monotonic_sec_counter();
+ connection->last_activity = MHD_monotonic_sec_counter ();
if (0 == (daemon->options & MHD_USE_TLS))
+ {
+ /* set default connection handlers */
+ MHD_set_http_callbacks_ (connection);
+ }
+ else
+ {
+#ifdef HTTPS_SUPPORT
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
+ gnutls_init_flags_t
+#else
+ unsigned int
+#endif
+ flags;
+
+ flags = GNUTLS_SERVER;
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
+ flags |= GNUTLS_NO_SIGNAL;
+#endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
+#if GNUTLS_VERSION_MAJOR >= 3
+ flags |= GNUTLS_NONBLOCK;
+#endif /* GNUTLS_VERSION_MAJOR >= 3*/
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
+ if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT))
+ flags |= GNUTLS_POST_HANDSHAKE_AUTH;
+#endif
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
+ if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA))
+ flags |= GNUTLS_ENABLE_EARLY_DATA;
+#endif
+ connection->tls_state = MHD_TLS_CONN_INIT;
+ MHD_set_https_callbacks (connection);
+ if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) ||
+ (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session,
+ daemon->priority_cache)))
{
- /* set default connection handlers */
- MHD_set_http_callbacks_ (connection);
- connection->recv_cls = &recv_param_adapter;
- connection->send_cls = &send_param_adapter;
+ if (NULL != connection->tls_session)
+ gnutls_deinit (connection->tls_session);
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection->addr);
+ free (connection);
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to initialise TLS session.\n"));
+#endif
+#if EPROTO
+ errno = EPROTO;
+#endif
+ return NULL;
}
- else
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030200)
+ if (! daemon->disable_alpn)
{
-#ifdef HTTPS_SUPPORT
- connection->recv_cls = &recv_tls_adapter;
- connection->send_cls = &send_tls_adapter;
- connection->state = MHD_TLS_CONNECTION_INIT;
- MHD_set_https_callbacks (connection);
- gnutls_init (&connection->tls_session,
- GNUTLS_SERVER);
- gnutls_priority_set (connection->tls_session,
- daemon->priority_cache);
- switch (daemon->cred_type)
- {
- /* set needed credentials for certificate authentication. */
- case GNUTLS_CRD_CERTIFICATE:
- gnutls_credentials_set (connection->tls_session,
- GNUTLS_CRD_CERTIFICATE,
- daemon->x509_cred);
- break;
- default:
+ gnutls_datum_t prts[2];
+ const char prt1[] = "http/1.1"; /* Registered code for HTTP/1.1 */
+ const char prt2[] = "http/1.0"; /* Registered code for HTTP/1.0 */
+
+ prts[0].data = (void*) prt1;
+ prts[0].size = MHD_STATICSTR_LEN_ (prt1);
+ prts[1].data = (void*) prt2;
+ prts[1].size = MHD_STATICSTR_LEN_ (prt2);
+ if (GNUTLS_E_SUCCESS !=
+ gnutls_alpn_set_protocols (connection->tls_session,
+ prts,
+ sizeof(prts) / sizeof(prts[0]),
+ 0 /* || GNUTLS_ALPN_SERVER_PRECEDENCE */))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to set ALPN protocols.\n"));
+#else /* ! HAVE_MESSAGES */
+ (void) 0; /* Mute compiler warning */
+#endif /* ! HAVE_MESSAGES */
+ }
+ }
+#endif /* GNUTLS_VERSION_NUMBER >= 0x030200 */
+ gnutls_session_set_ptr (connection->tls_session,
+ connection);
+ switch (daemon->cred_type)
+ {
+ /* set needed credentials for certificate authentication. */
+ case GNUTLS_CRD_CERTIFICATE:
+ gnutls_credentials_set (connection->tls_session,
+ GNUTLS_CRD_CERTIFICATE,
+ daemon->x509_cred);
+ break;
+ case GNUTLS_CRD_PSK:
+ gnutls_credentials_set (connection->tls_session,
+ GNUTLS_CRD_PSK,
+ daemon->psk_cred);
+ gnutls_psk_set_server_credentials_function (daemon->psk_cred,
+ &psk_gnutls_adapter);
+ break;
+ default:
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to setup TLS credentials: unknown credential type %d\n"),
- daemon->cred_type);
-#endif
- MHD_socket_close_chk_ (client_socket);
- MHD_ip_limit_del (daemon,
- addr,
- addrlen);
- free (connection->addr);
- free (connection);
- MHD_PANIC (_("Unknown credential type"));
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to setup TLS credentials: unknown credential type %d.\n"),
+ daemon->cred_type);
+#endif
+ gnutls_deinit (connection->tls_session);
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection->addr);
+ free (connection);
+ MHD_PANIC (_ ("Unknown credential type.\n"));
#if EINVAL
- errno = EINVAL;
+ errno = EINVAL;
#endif
- return MHD_NO;
- }
- gnutls_transport_set_ptr (connection->tls_session,
- (gnutls_transport_ptr_t) connection);
- gnutls_transport_set_pull_function (connection->tls_session,
- (gnutls_pull_func) &recv_param_adapter);
- gnutls_transport_set_push_function (connection->tls_session,
- (gnutls_push_func) &send_param_adapter);
-
- if (daemon->https_mem_trust)
- gnutls_certificate_server_set_request (connection->tls_session,
- GNUTLS_CERT_REQUEST);
+ return NULL;
+ }
+#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
+ gnutls_transport_set_int (connection->tls_session,
+ (int) (client_socket));
+#else /* GnuTLS before 3.1.9 or Win x64 */
+ gnutls_transport_set_ptr (connection->tls_session,
+ (gnutls_transport_ptr_t) (intptr_t) (client_socket));
+#endif /* GnuTLS before 3.1.9 */
+#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
+ gnutls_transport_set_push_function (connection->tls_session,
+ MHD_tls_push_func_);
+#endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
+ if (daemon->https_mem_trust)
+ gnutls_certificate_server_set_request (connection->tls_session,
+ GNUTLS_CERT_REQUEST);
#else /* ! HTTPS_SUPPORT */
- eno = EINVAL;
- goto cleanup;
+ MHD_socket_close_chk_ (client_socket);
+ MHD_ip_limit_del (daemon,
+ addr,
+ addrlen);
+ free (connection->addr);
+ free (connection);
+ MHD_PANIC (_ ("TLS connection on non-TLS daemon.\n"));
+ eno = EINVAL;
+ return NULL;
#endif /* ! HTTPS_SUPPORT */
- }
+ }
+
+ return connection;
+}
+
+
+#ifdef MHD_USE_THREADS
+/**
+ * Close prepared, but not yet processed connection.
+ * @param daemon the daemon
+ * @param connection the connection to close
+ */
+static void
+new_connection_close_ (struct MHD_Daemon *daemon,
+ struct MHD_Connection *connection)
+{
+ mhd_assert (connection->daemon == daemon);
+ mhd_assert (! connection->in_cleanup);
+ mhd_assert (NULL == connection->next);
+ mhd_assert (NULL == connection->nextX);
+#ifdef EPOLL_SUPPORT
+ mhd_assert (NULL == connection->nextE);
+#endif /* EPOLL_SUPPORT */
+
+#ifdef HTTPS_SUPPORT
+ if (NULL != connection->tls_session)
+ {
+ mhd_assert (0 != (daemon->options & MHD_USE_TLS));
+ gnutls_deinit (connection->tls_session);
+ }
+#endif /* HTTPS_SUPPORT */
+ MHD_socket_close_chk_ (connection->socket_fd);
+ MHD_ip_limit_del (daemon,
+ connection->addr,
+ connection->addr_len);
+ free (connection->addr);
+ free (connection);
+}
+
+
+#endif /* MHD_USE_THREADS */
+
+/**
+ * Finally insert the new connection to the list of connections
+ * served by the daemon and start processing.
+ * @remark To be called only from thread that process
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon daemon that manages the connection
+ * @param connection the newly created connection
+ * @return #MHD_YES on success, #MHD_NO on error
+ */
+static enum MHD_Result
+new_connection_process_ (struct MHD_Daemon *daemon,
+ struct MHD_Connection *connection)
+{
+ int eno = 0;
+
+ mhd_assert (connection->daemon == daemon);
+
+#ifdef MHD_USE_THREADS
+ /* Function manipulate connection and timeout DL-lists,
+ * must be called only within daemon thread. */
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
+
+ /* Allocate memory pool in the processing thread so
+ * intensively used memory area is allocated in "good"
+ * (for the thread) memory region. It is important with
+ * NUMA and/or complex cache hierarchy. */
+ connection->pool = MHD_pool_create (daemon->pool_size);
+ if (NULL == connection->pool)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ MHD_socket_close_chk_ (connection->socket_fd);
+ MHD_ip_limit_del (daemon,
+ connection->addr,
+ connection->addr_len);
+ free (connection);
+#if ENOMEM
+ errno = ENOMEM;
+#endif
+ return MHD_NO;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ /* Firm check under lock. */
+ if (daemon->connections >= daemon->connection_limit)
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ /* above connection limit - reject */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Server reached connection limit. Closing inbound connection.\n"));
+#endif
+#if ENFILE
+ eno = ENFILE;
+#endif
+ goto cleanup;
+ }
+ daemon->connections++;
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
{
XDLL_insert (daemon->normal_timeout_head,
@@ -2595,110 +2757,275 @@
connection);
}
DLL_insert (daemon->connections_head,
- daemon->connections_tail,
- connection);
+ daemon->connections_tail,
+ connection);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
-
+#endif
if (NULL != daemon->notify_connection)
daemon->notify_connection (daemon->notify_connection_cls,
connection,
&connection->socket_context,
MHD_CONNECTION_NOTIFY_STARTED);
-
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/* attempt to create handler thread */
if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+ {
+ if (! MHD_create_named_thread_ (&connection->pid,
+ "MHD-connection",
+ daemon->thread_stack_size,
+ &thread_main_handle_connection,
+ connection))
{
- if (! MHD_create_named_thread_ (&connection->pid,
- "MHD-connection",
- daemon->thread_stack_size,
- &thread_main_handle_connection,
- connection))
- {
- eno = errno;
+ eno = errno;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Failed to create a thread: %s\n",
- MHD_strerror_ (eno));
+ MHD_DLOG (daemon,
+ _ ("Failed to create a thread: %s\n"),
+ MHD_strerror_ (eno));
#endif
- goto cleanup;
- }
+ goto cleanup;
}
+ }
else
- if ( (MHD_YES == external_add) &&
- (MHD_ITC_IS_VALID_(daemon->itc)) &&
- (! MHD_itc_activate_ (daemon->itc, "n")) )
+ connection->pid = daemon->pid;
+#endif
+#ifdef EPOLL_SUPPORT
+ if (0 != (daemon->options & MHD_USE_EPOLL))
+ {
+ if (0 == (daemon->options & MHD_USE_TURBO))
+ {
+ struct epoll_event event;
+
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = connection;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ connection->socket_fd,
+ &event))
{
+ eno = errno;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to signal new connection via inter-thread communication channel."));
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
+ goto cleanup;
}
-#ifdef EPOLL_SUPPORT
- if (0 != (daemon->options & MHD_USE_EPOLL))
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ else
{
- if (0 == (daemon->options & MHD_USE_TURBO))
- {
- struct epoll_event event;
-
- event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
- event.data.ptr = connection;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- client_socket,
- &event))
- {
- eno = errno;
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- goto cleanup;
- }
- connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
- }
- else
- {
- connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
- | MHD_EPOLL_STATE_IN_EREADY_EDLL;
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- connection);
- }
+ connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
+ | MHD_EPOLL_STATE_WRITE_READY
+ | MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
}
+ }
#endif
- daemon->connections++;
+
return MHD_YES;
- cleanup:
+
+cleanup:
if (NULL != daemon->notify_connection)
daemon->notify_connection (daemon->notify_connection_cls,
connection,
&connection->socket_context,
MHD_CONNECTION_NOTIFY_CLOSED);
- MHD_socket_close_chk_ (client_socket);
+#ifdef HTTPS_SUPPORT
+ if (NULL != connection->tls_session)
+ gnutls_deinit (connection->tls_session);
+#endif /* HTTPS_SUPPORT */
+ MHD_socket_close_chk_ (connection->socket_fd);
MHD_ip_limit_del (daemon,
- addr,
- addrlen);
+ connection->addr,
+ connection->addr_len);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
- XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
- }
+ {
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ }
DLL_remove (daemon->connections_head,
- daemon->connections_tail,
- connection);
+ daemon->connections_tail,
+ connection);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
MHD_pool_destroy (connection->pool);
free (connection->addr);
free (connection);
- errno = eno;
+ if (0 != eno)
+ errno = eno;
+ else
+ errno = EINVAL;
return MHD_NO;
}
/**
+ * Add another client connection to the set of connections
+ * managed by MHD. This API is usually not needed (since
+ * MHD will accept inbound connections on the server socket).
+ * Use this API in special cases, for example if your HTTP
+ * server is behind NAT and needs to connect out to the
+ * HTTP client.
+ *
+ * The given client socket will be managed (and closed!) by MHD after
+ * this call and must no longer be used directly by the application
+ * afterwards.
+ *
+ * @param daemon daemon that manages the connection
+ * @param client_socket socket to manage (MHD will expect
+ * to receive an HTTP request from this socket next).
+ * @param addr IP address of the client
+ * @param addrlen number of bytes in @a addr
+ * @param external_add perform additional operations needed due
+ * to the application calling us directly
+ * @param non_blck indicate that socket in non-blocking mode
+ * @param sk_spipe_supprs indicate that the @a client_socket has
+ * set SIGPIPE suppression
+ * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
+ * @return #MHD_YES on success, #MHD_NO if this daemon could
+ * not handle the connection (i.e. malloc failed, etc).
+ * The socket will be closed in any case; 'errno' is
+ * set to indicate further details about the error.
+ */
+static enum MHD_Result
+internal_add_connection (struct MHD_Daemon *daemon,
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen,
+ bool external_add,
+ bool non_blck,
+ bool sk_spipe_supprs,
+ enum MHD_tristate sk_is_nonip)
+{
+ struct MHD_Connection *connection;
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ /* Direct add to master daemon could never happen. */
+ mhd_assert ((NULL == daemon->worker_pool));
+#endif
+
+ if ( (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, NULL)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("New connection socket descriptor (%d) is not less " \
+ "than FD_SETSIZE (%d).\n"),
+ (int) client_socket,
+ (int) FD_SETSIZE);
+#endif
+ MHD_socket_close_chk_ (client_socket);
+#if ENFILE
+ errno = ENFILE;
+#endif
+ return MHD_NO;
+ }
+
+ if ( (0 == (daemon->options & MHD_USE_EPOLL)) &&
+ (! non_blck) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Epoll mode supports only non-blocking sockets\n"));
+#endif
+ MHD_socket_close_chk_ (client_socket);
+#if EINVAL
+ errno = EINVAL;
+#endif
+ return MHD_NO;
+ }
+
+ connection = new_connection_prepare_ (daemon,
+ client_socket,
+ addr, addrlen,
+ external_add,
+ non_blck,
+ sk_spipe_supprs,
+ sk_is_nonip);
+ if (NULL == connection)
+ return MHD_NO;
+
+ if ((external_add) &&
+ (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)))
+ {
+ /* Connection is added externally and MHD is handling its own threads. */
+ MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
+ DLL_insert (daemon->new_connections_head,
+ daemon->new_connections_tail,
+ connection);
+ daemon->have_new = true;
+ MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
+
+ /* The rest of connection processing must be handled in
+ * the daemon thread. */
+ if ((MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc, "n")))
+ {
+ #ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to signal new connection via inter-thread " \
+ "communication channel.\n"));
+ #endif
+ }
+ return MHD_YES;
+ }
+
+ return new_connection_process_ (daemon, connection);
+}
+
+
+static void
+new_connections_list_process_ (struct MHD_Daemon *daemon)
+{
+ struct MHD_Connection *local_head;
+ struct MHD_Connection *local_tail;
+ mhd_assert (daemon->have_new);
+ mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
+
+ /* Detach DL-list of new connections from the daemon for
+ * following local processing. */
+ MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
+ mhd_assert (NULL != daemon->new_connections_head);
+ local_head = daemon->new_connections_head;
+ local_tail = daemon->new_connections_tail;
+ daemon->new_connections_head = NULL;
+ daemon->new_connections_tail = NULL;
+ daemon->have_new = false;
+ MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
+ (void) local_head; /* Mute compiler warning */
+
+ /* Process new connections in FIFO order. */
+ do
+ {
+ struct MHD_Connection *c; /**< Currently processed connection */
+
+ c = local_tail;
+ DLL_remove (local_head,
+ local_tail,
+ c);
+ mhd_assert (daemon == c->daemon);
+ if (MHD_NO == new_connection_process_ (daemon, c))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to start serving new connection.\n"));
+#endif
+ (void) 0;
+ }
+ } while (NULL != local_tail);
+
+}
+
+
+/**
* Internal version of ::MHD_suspend_connection().
*
* @remark In thread-per-connection mode: can be called from any thread,
@@ -2712,56 +3039,65 @@
{
struct MHD_Daemon *daemon = connection->daemon;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if (connection->resuming)
- {
- /* suspending again while we didn't even complete resuming yet */
- connection->resuming = false;
- MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
- return;
- }
+ {
+ /* suspending again while we didn't even complete resuming yet */
+ connection->resuming = false;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ return;
+ }
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
- if (connection->connection_timeout == daemon->connection_timeout)
- XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- connection);
- else
- XDLL_remove (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- connection);
- }
+ {
+ if (connection->connection_timeout == daemon->connection_timeout)
+ XDLL_remove (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ connection);
+ else
+ XDLL_remove (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ connection);
+ }
DLL_remove (daemon->connections_head,
daemon->connections_tail,
connection);
- EXTRA_CHECK (! connection->suspended);
+ mhd_assert (! connection->suspended);
DLL_insert (daemon->suspended_connections_head,
daemon->suspended_connections_tail,
connection);
connection->suspended = true;
#ifdef EPOLL_SUPPORT
if (0 != (daemon->options & MHD_USE_EPOLL))
+ {
+ if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
{
- if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
- {
- EDLL_remove (daemon->eready_head,
- daemon->eready_tail,
- connection);
- connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
- {
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- connection->socket_fd,
- NULL))
- MHD_PANIC (_("Failed to remove FD from epoll set\n"));
- connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
- }
- connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
+ {
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ connection->socket_fd,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
}
+ connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
+ }
#endif
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
}
@@ -2799,19 +3135,27 @@
void
MHD_suspend_connection (struct MHD_Connection *connection)
{
- struct MHD_Daemon * const daemon = connection->daemon;
+ struct MHD_Daemon *const daemon = connection->daemon;
+
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
- MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
+ MHD_PANIC (_ (
+ "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
#ifdef UPGRADE_SUPPORT
if (NULL != connection->urh)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error: connection scheduled for \"upgrade\" cannot be suspended"));
+ MHD_DLOG (daemon,
+ _ (
+ "Error: connection scheduled for \"upgrade\" cannot be suspended.\n"));
#endif /* HAVE_MESSAGES */
- return;
- }
+ return;
+ }
#endif /* UPGRADE_SUPPORT */
internal_suspend_connection_ (connection);
}
@@ -2828,23 +3172,28 @@
void
MHD_resume_connection (struct MHD_Connection *connection)
{
- struct MHD_Daemon *daemon;
+ struct MHD_Daemon *daemon = connection->daemon;
- daemon = connection->daemon;
if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
- MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
+ MHD_PANIC (_ (
+ "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
connection->resuming = true;
daemon->resuming = true;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
+#endif
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
(! MHD_itc_activate_ (daemon->itc, "r")) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to signal resume via inter-thread communication channel."));
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to signal resume via inter-thread communication channel.\n"));
#endif
- }
+ }
}
@@ -2857,108 +3206,135 @@
* @param daemon daemon context
* @return #MHD_YES if a connection was actually resumed
*/
-static int
+static enum MHD_Result
resume_suspended_connections (struct MHD_Daemon *daemon)
{
struct MHD_Connection *pos;
struct MHD_Connection *prev = NULL;
- int ret;
- const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
+ enum MHD_Result ret;
+ const bool used_thr_p_c = (0 != (daemon->options
+ & MHD_USE_THREAD_PER_CONNECTION));
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ mhd_assert (NULL == daemon->worker_pool);
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif
ret = MHD_NO;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if (daemon->resuming)
+ {
prev = daemon->suspended_connections_tail;
+ /* During shutdown check for resuming is forced. */
+ mhd_assert ((NULL != prev) || (daemon->shutdown) || \
+ (0 != (daemon->options & MHD_ALLOW_UPGRADE)));
+ }
- EXTRA_CHECK(NULL != next);
daemon->resuming = false;
while (NULL != (pos = prev))
- {
+ {
#ifdef UPGRADE_SUPPORT
- struct MHD_UpgradeResponseHandle * const urh = pos->urh;
+ struct MHD_UpgradeResponseHandle *const urh = pos->urh;
#else /* ! UPGRADE_SUPPORT */
- static const void * const urh = NULL;
+ static const void *const urh = NULL;
#endif /* ! UPGRADE_SUPPORT */
- prev = pos->prev;
- if ( (! pos->resuming)
+ prev = pos->prev;
+ if ( (! pos->resuming)
#ifdef UPGRADE_SUPPORT
- || ( (NULL != urh) &&
- ( (! urh->was_closed) ||
- (! urh->clean_ready) ) )
+ || ( (NULL != urh) &&
+ ( (! urh->was_closed) ||
+ (! urh->clean_ready) ) )
#endif /* UPGRADE_SUPPORT */
)
- continue;
- ret = MHD_YES;
- EXTRA_CHECK (pos->suspended);
- DLL_remove (daemon->suspended_connections_head,
- daemon->suspended_connections_tail,
+ continue;
+ ret = MHD_YES;
+ mhd_assert (pos->suspended);
+ DLL_remove (daemon->suspended_connections_head,
+ daemon->suspended_connections_tail,
+ pos);
+ pos->suspended = false;
+ if (NULL == urh)
+ {
+ DLL_insert (daemon->connections_head,
+ daemon->connections_tail,
pos);
- pos->suspended = false;
- if (NULL == urh)
- {
- DLL_insert (daemon->connections_head,
- daemon->connections_tail,
- pos);
- if (!used_thr_p_c)
- {
- /* Reset timeout timer on resume. */
- if (0 != pos->connection_timeout)
- pos->last_activity = MHD_monotonic_sec_counter();
-
- if (pos->connection_timeout == daemon->connection_timeout)
- XDLL_insert (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- pos);
- else
- XDLL_insert (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- pos);
- }
+ if (! used_thr_p_c)
+ {
+ /* Reset timeout timer on resume. */
+ if (0 != pos->connection_timeout)
+ pos->last_activity = MHD_monotonic_sec_counter ();
+
+ if (pos->connection_timeout == daemon->connection_timeout)
+ XDLL_insert (daemon->normal_timeout_head,
+ daemon->normal_timeout_tail,
+ pos);
+ else
+ XDLL_insert (daemon->manual_timeout_head,
+ daemon->manual_timeout_tail,
+ pos);
+ }
#ifdef EPOLL_SUPPORT
- if (0 != (daemon->options & MHD_USE_EPOLL))
- {
- if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
- MHD_PANIC ("Resumed connection was already in EREADY set\n");
- /* we always mark resumed connections as ready, as we
- might have missed the edge poll event during suspension */
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
- MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
- pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
- }
+ if (0 != (daemon->options & MHD_USE_EPOLL))
+ {
+ if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ MHD_PANIC ("Resumed connection was already in EREADY set.\n");
+ /* we always mark resumed connections as ready, as we
+ might have missed the edge poll event during suspension */
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
+ | MHD_EPOLL_STATE_READ_READY
+ | MHD_EPOLL_STATE_WRITE_READY;
+ pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
+ }
#endif
- }
+ }
#ifdef UPGRADE_SUPPORT
- else
- {
- /* Data forwarding was finished (for TLS connections) AND
- * application was closed upgraded connection.
- * Insert connection into cleanup list. */
- DLL_insert (daemon->cleanup_head,
- daemon->cleanup_tail,
- pos);
-
- }
-#endif /* UPGRADE_SUPPORT */
- pos->resuming = false;
+ else
+ {
+ /* Data forwarding was finished (for TLS connections) AND
+ * application was closed upgraded connection.
+ * Insert connection into cleanup list. */
+
+ if ( (NULL != daemon->notify_completed) &&
+ (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (pos->client_aware) )
+ {
+ daemon->notify_completed (daemon->notify_completed_cls,
+ pos,
+ &pos->client_context,
+ MHD_REQUEST_TERMINATED_COMPLETED_OK);
+ pos->client_aware = false;
+ }
+ DLL_insert (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ pos);
+ daemon->data_already_pending = true;
}
+#endif /* UPGRADE_SUPPORT */
+ pos->resuming = false;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
if ( (used_thr_p_c) &&
(MHD_NO != ret) )
- { /* Wake up suspended connections. */
- if (! MHD_itc_activate_(daemon->itc,
- "w"))
- {
+ { /* Wake up suspended connections. */
+ if (! MHD_itc_activate_ (daemon->itc,
+ "w"))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to signal resume of connection via inter-thread communication channel."));
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to signal resume of connection via inter-thread communication channel.\n"));
#endif
- }
}
+ }
return ret;
}
@@ -2979,8 +3355,6 @@
* this call and must no longer be used directly by the application
* afterwards.
*
- * Per-IP connection limits are ignored when using this API.
- *
* @param daemon daemon that manages the connection
* @param client_socket socket to manage (MHD will expect
* to receive an HTTP request from this socket next).
@@ -2992,39 +3366,123 @@
* set to indicate further details about the error.
* @ingroup specialized
*/
-int
+enum MHD_Result
MHD_add_connection (struct MHD_Daemon *daemon,
- MHD_socket client_socket,
- const struct sockaddr *addr,
- socklen_t addrlen)
+ MHD_socket client_socket,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
{
bool sk_nonbl;
+ bool sk_spipe_supprs;
+
+ /* NOT thread safe with internal thread. TODO: fix thread safety. */
+ if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
+ (daemon->connection_limit <= daemon->connections))
+ MHD_cleanup_connections (daemon);
+
+#ifdef HAVE_MESSAGES
+ if ((0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
+ (0 == (daemon->options & MHD_USE_ITC)))
+ {
+ MHD_DLOG (daemon,
+ _ ("MHD_add_connection() has been called for daemon started"
+ " without MHD_USE_ITC flag.\nDaemon will not process newly"
+ " added connection until any activity occurs in already"
+ " added sockets.\n"));
+ }
+#endif /* HAVE_MESSAGES */
+
if (! MHD_socket_nonblocking_ (client_socket))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set nonblocking mode on new client socket: %s\n"),
- MHD_socket_last_strerr_());
+ MHD_DLOG (daemon,
+ _ ("Failed to set nonblocking mode on new client socket: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- sk_nonbl = 0;
+ sk_nonbl = false;
+ }
+ else
+ sk_nonbl = true;
+
+#ifndef MHD_WINSOCK_SOCKETS
+ sk_spipe_supprs = false;
+#else /* MHD_WINSOCK_SOCKETS */
+ sk_spipe_supprs = true; /* Nothing to suppress on W32 */
+#endif /* MHD_WINSOCK_SOCKETS */
+#if defined(MHD_socket_nosignal_)
+ if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (client_socket))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to suppress SIGPIPE on new client socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#else /* ! HAVE_MESSAGES */
+ (void) 0; /* Mute compiler warning */
+#endif /* ! HAVE_MESSAGES */
+#ifndef MSG_NOSIGNAL
+ /* Application expects that SIGPIPE will be suppressed,
+ * but suppression failed and SIGPIPE cannot be suppressed with send(). */
+ if (! daemon->sigpipe_blocked)
+ {
+ int err = MHD_socket_get_error_ ();
+ MHD_socket_close_ (client_socket);
+ MHD_socket_fset_error_ (err);
+ return MHD_NO;
}
+#endif /* MSG_NOSIGNAL */
+ }
else
- sk_nonbl = !0;
+ sk_spipe_supprs = true;
+#endif /* MHD_socket_nosignal_ */
if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
(! MHD_socket_noninheritable_ (client_socket)) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set noninheritable mode on new client socket.\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to set noninheritable mode on new client socket.\n"));
#endif
+ }
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != daemon->worker_pool)
+ {
+ unsigned int i;
+ /* have a pool, try to find a pool with capacity; we use the
+ socket as the initial offset into the pool for load
+ balancing */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
+ {
+ struct MHD_Daemon *const worker =
+ &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
+ if (worker->connections < worker->connection_limit)
+ return internal_add_connection (worker,
+ client_socket,
+ addr,
+ addrlen,
+ true,
+ sk_nonbl,
+ sk_spipe_supprs,
+ _MHD_UNKNOWN);
}
+ /* all pools are at their connection limit, must refuse */
+ MHD_socket_close_chk_ (client_socket);
+#if ENFILE
+ errno = ENFILE;
+#endif
+ return MHD_NO;
+ }
+#endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
+
return internal_add_connection (daemon,
- client_socket,
- addr,
+ client_socket,
+ addr,
addrlen,
- MHD_YES,
- sk_nonbl);
+ true,
+ sk_nonbl,
+ sk_spipe_supprs,
+ _MHD_UNKNOWN);
}
@@ -3042,7 +3500,7 @@
* a return code of #MHD_NO only refers to the actual
* accept() system call.
*/
-static int
+static enum MHD_Result
MHD_accept_connection (struct MHD_Daemon *daemon)
{
#if HAVE_INET6
@@ -3055,6 +3513,12 @@
MHD_socket s;
MHD_socket fd;
bool sk_nonbl;
+ bool sk_spipe_supprs;
+
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
addrlen = sizeof (addrstorage);
memset (addr,
@@ -3067,94 +3531,141 @@
s = accept4 (fd,
addr,
&addrlen,
- MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK);
- sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
+ SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO
+ | SOCK_NOSIGPIPE_OR_ZERO);
+ sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0);
+#ifndef MHD_WINSOCK_SOCKETS
+ sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0);
+#else /* MHD_WINSOCK_SOCKETS */
+ sk_spipe_supprs = true; /* Nothing to suppress on W32 */
+#endif /* MHD_WINSOCK_SOCKETS */
#else /* ! USE_ACCEPT4 */
s = accept (fd,
addr,
&addrlen);
- sk_nonbl = 0;
+ sk_nonbl = false;
+#ifndef MHD_WINSOCK_SOCKETS
+ sk_spipe_supprs = false;
+#else /* MHD_WINSOCK_SOCKETS */
+ sk_spipe_supprs = true; /* Nothing to suppress on W32 */
+#endif /* MHD_WINSOCK_SOCKETS */
#endif /* ! USE_ACCEPT4 */
if ( (MHD_INVALID_SOCKET == s) ||
(addrlen <= 0) )
- {
- const int err = MHD_socket_get_error_ ();
+ {
+ const int err = MHD_socket_get_error_ ();
- /* This could be a common occurance with multiple worker threads */
- if (MHD_SCKT_ERR_IS_ (err,
- MHD_SCKT_EINVAL_))
- return MHD_NO; /* can happen during shutdown */
- if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err))
- return MHD_NO; /* do not print error if client just disconnected early */
+ /* This could be a common occurrence with multiple worker threads */
+ if (MHD_SCKT_ERR_IS_ (err,
+ MHD_SCKT_EINVAL_))
+ return MHD_NO; /* can happen during shutdown */
+ if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err))
+ return MHD_NO; /* do not print error if client just disconnected early */
#ifdef HAVE_MESSAGES
- if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
+ if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
+ MHD_DLOG (daemon,
+ _ ("Error accepting connection: %s\n"),
+ MHD_socket_strerr_ (err));
+#endif
+ if (MHD_INVALID_SOCKET != s)
+ {
+ MHD_socket_close_chk_ (s);
+ }
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
+ {
+ /* system/process out of resources */
+ if (0 == daemon->connections)
+ {
+#ifdef HAVE_MESSAGES
+ /* Not setting 'at_limit' flag, as there is no way it
+ would ever be cleared. Instead trying to produce
+ bit fat ugly warning. */
MHD_DLOG (daemon,
- _("Error accepting connection: %s\n"),
- MHD_socket_strerr_(err));
+ _ (
+ "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
#endif
- if (MHD_INVALID_SOCKET != s)
- {
- MHD_socket_close_chk_ (s);
- }
- if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
- {
- /* system/process out of resources */
- if (0 == daemon->connections)
- {
-#ifdef HAVE_MESSAGES
- /* Not setting 'at_limit' flag, as there is no way it
- would ever be cleared. Instead trying to produce
- bit fat ugly warning. */
- MHD_DLOG (daemon,
- _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
+ }
+ else
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ daemon->at_limit = true;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
#endif
- }
- else
- {
- daemon->at_limit = true;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
- (unsigned int) daemon->connections);
+ MHD_DLOG (daemon,
+ _ (
+ "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
+ (unsigned int) daemon->connections);
#endif
- }
- }
- return MHD_NO;
+ }
}
-#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
+ return MHD_NO;
+ }
+#if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
if (! MHD_socket_nonblocking_ (s))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set nonblocking mode on incoming connection socket: %s\n"),
- MHD_socket_last_strerr_());
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to set nonblocking mode on incoming connection socket: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- }
+ }
else
- sk_nonbl = !0;
+ sk_nonbl = true;
#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
-#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
+#if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
if (! MHD_socket_noninheritable_ (s))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set noninheritable mode on incoming connection socket.\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to set noninheritable mode on incoming connection socket.\n"));
#endif
- }
+ }
#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
+#if defined(MHD_socket_nosignal_)
+ if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to suppress SIGPIPE on incoming connection socket: %s\n"),
+ MHD_socket_last_strerr_ ());
+#else /* ! HAVE_MESSAGES */
+ (void) 0; /* Mute compiler warning */
+#endif /* ! HAVE_MESSAGES */
+#ifndef MSG_NOSIGNAL
+ /* Application expects that SIGPIPE will be suppressed,
+ * but suppression failed and SIGPIPE cannot be suppressed with send(). */
+ if (! daemon->sigpipe_blocked)
+ {
+ MHD_socket_close_ (s);
+ return MHD_NO;
+ }
+#endif /* MSG_NOSIGNAL */
+ }
+ else
+ sk_spipe_supprs = true;
+#endif /* MHD_socket_nosignal_ */
#ifdef HAVE_MESSAGES
-#if DEBUG_CONNECT
+#if _MHD_DEBUG_CONNECT
MHD_DLOG (daemon,
- _("Accepted connection on socket %d\n"),
+ _ ("Accepted connection on socket %d\n"),
s);
#endif
#endif
(void) internal_add_connection (daemon,
s,
- addr,
+ addr,
addrlen,
- MHD_NO,
- sk_nonbl);
+ false,
+ sk_nonbl,
+ sk_spipe_supprs,
+ daemon->listen_is_unix);
return MHD_YES;
}
@@ -3172,90 +3683,103 @@
MHD_cleanup_connections (struct MHD_Daemon *daemon)
{
struct MHD_Connection *pos;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
while (NULL != (pos = daemon->cleanup_tail))
- {
- DLL_remove (daemon->cleanup_head,
- daemon->cleanup_tail,
- pos);
- MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
-
- if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (! pos->thread_joined) &&
- (! MHD_join_thread_ (pos->pid)) )
- MHD_PANIC (_("Failed to join a thread\n"));
+ {
+ DLL_remove (daemon->cleanup_head,
+ daemon->cleanup_tail,
+ pos);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (! pos->thread_joined) &&
+ (! MHD_join_thread_ (pos->pid.handle)) )
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+#endif
#ifdef UPGRADE_SUPPORT
- cleanup_upgraded_connection (pos);
+ cleanup_upgraded_connection (pos);
#endif /* UPGRADE_SUPPORT */
- MHD_pool_destroy (pos->pool);
+ MHD_pool_destroy (pos->pool);
#ifdef HTTPS_SUPPORT
- if (NULL != pos->tls_session)
- gnutls_deinit (pos->tls_session);
+ if (NULL != pos->tls_session)
+ gnutls_deinit (pos->tls_session);
#endif /* HTTPS_SUPPORT */
- daemon->connections--;
- daemon->at_limit = false;
- /* clean up the connection */
- if (NULL != daemon->notify_connection)
- daemon->notify_connection (daemon->notify_connection_cls,
- pos,
- &pos->socket_context,
- MHD_CONNECTION_NOTIFY_CLOSED);
- MHD_ip_limit_del (daemon,
- pos->addr,
- pos->addr_len);
+ /* clean up the connection */
+ if (NULL != daemon->notify_connection)
+ daemon->notify_connection (daemon->notify_connection_cls,
+ pos,
+ &pos->socket_context,
+ MHD_CONNECTION_NOTIFY_CLOSED);
+ MHD_ip_limit_del (daemon,
+ pos->addr,
+ pos->addr_len);
#ifdef EPOLL_SUPPORT
- if (0 != (daemon->options & MHD_USE_EPOLL))
- {
- if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
- {
- EDLL_remove (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- if ( (-1 != daemon->epoll_fd) &&
- (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
- {
- /* epoll documentation suggests that closing a FD
- automatically removes it from the epoll set; however,
- this is not true as if we fail to do manually remove it,
- we are still seeing an event for this fd in epoll,
- causing grief (use-after-free...) --- at least on my
- system. */
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- pos->socket_fd,
- NULL))
- MHD_PANIC (_("Failed to remove FD from epoll set\n"));
- pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
- }
- }
+ if (0 != (daemon->options & MHD_USE_EPOLL))
+ {
+ if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ if ( (-1 != daemon->epoll_fd) &&
+ (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
+ {
+ /* epoll documentation suggests that closing a FD
+ automatically removes it from the epoll set; however,
+ this is not true as if we fail to do manually remove it,
+ we are still seeing an event for this fd in epoll,
+ causing grief (use-after-free...) --- at least on my
+ system. */
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ pos->socket_fd,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ }
#endif
- if (NULL != pos->response)
- {
- MHD_destroy_response (pos->response);
- pos->response = NULL;
- }
- if (MHD_INVALID_SOCKET != pos->socket_fd)
- MHD_socket_close_chk_ (pos->socket_fd);
- if (NULL != pos->addr)
- free (pos->addr);
- free (pos);
-
- MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ if (NULL != pos->response)
+ {
+ MHD_destroy_response (pos->response);
+ pos->response = NULL;
}
+ if (MHD_INVALID_SOCKET != pos->socket_fd)
+ MHD_socket_close_chk_ (pos->socket_fd);
+ if (NULL != pos->addr)
+ free (pos->addr);
+ free (pos);
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ daemon->connections--;
+ daemon->at_limit = false;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
}
/**
- * Obtain timeout value for `select()` for this daemon (only needed if
- * connection timeout is used). The returned value is how long
- * `select()` or `poll()` should at most block, not the timeout value set
- * for connections. This function MUST NOT be called if MHD is
- * running with #MHD_USE_THREAD_PER_CONNECTION.
+ * Obtain timeout value for polling function for this daemon.
+ * This function set value to amount of milliseconds for which polling
+ * function (`select()` or `poll()`) should at most block, not the
+ * timeout value set for connections.
+ * It is important to always use this function, even if connection
+ * timeout is not set as in some cases MHD may already have more
+ * data to process on next turn (data pending in TLS buffers,
+ * connections are already ready with epoll etc.) and returned timeout
+ * will be zero.
* @remark To be called only from thread that process
* daemon's select()/poll()/etc.
*
@@ -3266,86 +3790,119 @@
* necessitate the use of a timeout right now).
* @ingroup event
*/
-int
+enum MHD_Result
MHD_get_timeout (struct MHD_Daemon *daemon,
- MHD_UNSIGNED_LONG_LONG *timeout)
+ MHD_UNSIGNED_LONG_LONG *timeout)
{
time_t earliest_deadline;
time_t now;
struct MHD_Connection *pos;
bool have_timeout;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
+
if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Illegal call to MHD_get_timeout\n"));
+ MHD_DLOG (daemon,
+ _ ("Illegal call to MHD_get_timeout.\n"));
#endif
- return MHD_NO;
- }
-
+ return MHD_NO;
+ }
if (daemon->data_already_pending)
- {
- /* Some data already waiting to be processed. */
- *timeout = 0;
- return MHD_YES;
- }
-
+ {
+ /* Some data already waiting to be processed. */
+ *timeout = 0;
+ return MHD_YES;
+ }
#ifdef EPOLL_SUPPORT
if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
((NULL != daemon->eready_head)
#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
- || (NULL != daemon->eready_urh_head)
+ || (NULL != daemon->eready_urh_head)
#endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
- ) )
- {
- /* Some connection(s) already have some data pending. */
- *timeout = 0;
- return MHD_YES;
- }
+ ) )
+ {
+ /* Some connection(s) already have some data pending. */
+ *timeout = 0;
+ return MHD_YES;
+ }
#endif /* EPOLL_SUPPORT */
have_timeout = false;
earliest_deadline = 0; /* avoid compiler warnings */
for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
+ {
+ if (0 != pos->connection_timeout)
{
- if (0 != pos->connection_timeout)
- {
- if ( (! have_timeout) ||
- (earliest_deadline - pos->last_activity > pos->connection_timeout) )
- earliest_deadline = pos->last_activity + pos->connection_timeout;
- have_timeout = true;
- }
+ if ( (! have_timeout) ||
+ (earliest_deadline - pos->last_activity > pos->connection_timeout) )
+ earliest_deadline = pos->last_activity + pos->connection_timeout;
+ have_timeout = true;
}
+ }
/* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
pos = daemon->normal_timeout_tail;
if ( (NULL != pos) &&
(0 != pos->connection_timeout) )
- {
- if ( (! have_timeout) ||
- (earliest_deadline - pos->connection_timeout > pos->last_activity) )
- earliest_deadline = pos->last_activity + pos->connection_timeout;
- have_timeout = true;
- }
+ {
+ if ( (! have_timeout) ||
+ (earliest_deadline - pos->connection_timeout > pos->last_activity) )
+ earliest_deadline = pos->last_activity + pos->connection_timeout;
+ have_timeout = true;
+ }
if (! have_timeout)
return MHD_NO;
- now = MHD_monotonic_sec_counter();
+ now = MHD_monotonic_sec_counter ();
if (earliest_deadline < now)
*timeout = 0;
else
- {
- const time_t second_left = earliest_deadline - now;
- if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */
- *timeout = ULLONG_MAX;
- else
- *timeout = 1000LL * second_left;
+ {
+ const time_t second_left = earliest_deadline - now;
+
+ if (((unsigned long long) second_left) > ULLONG_MAX / 1000)
+ *timeout = ULLONG_MAX;
+ else
+ *timeout = 1000LLU * (unsigned long long) second_left;
}
return MHD_YES;
}
/**
+ * Obtain timeout value for polling function for this daemon.
+ * @remark To be called only from the thread that processes
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon the daemon to query for timeout
+ * @param max_timeout the maximum return value (in milliseconds),
+ * ignored if set to '-1'
+ * @return timeout value in milliseconds or -1 if no timeout is expected.
+ */
+static int
+get_timeout_millisec_ (struct MHD_Daemon *daemon,
+ int32_t max_timeout)
+{
+ MHD_UNSIGNED_LONG_LONG ulltimeout;
+ if (0 == max_timeout)
+ return 0;
+
+ if (MHD_NO == MHD_get_timeout (daemon, &ulltimeout))
+ return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
+
+ if ( (0 > max_timeout) ||
+ ((uint32_t) max_timeout > ulltimeout) )
+ return (INT_MAX < ulltimeout) ? INT_MAX : (int) ulltimeout;
+
+ return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
+}
+
+
+/**
* Internal version of #MHD_run_from_select().
*
* @param daemon daemon to run select loop for
@@ -3355,7 +3912,7 @@
* @return #MHD_NO on serious errors, #MHD_YES on success
* @ingroup event
*/
-static int
+static enum MHD_Result
internal_run_from_select (struct MHD_Daemon *daemon,
const fd_set *read_fd_set,
const fd_set *write_fd_set,
@@ -3375,11 +3932,15 @@
/* Clear ITC to avoid spinning select */
/* Do it before any other processing so new signals
will trigger select again and will be processed */
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
(FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
read_fd_set)) )
MHD_itc_clear_ (daemon->itc);
+ /* Process externally added connection if any */
+ if (daemon->have_new)
+ new_connections_list_process_ (daemon);
+
/* select connection thread handling type */
if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
(! daemon->was_quiesced) &&
@@ -3388,49 +3949,49 @@
(void) MHD_accept_connection (daemon);
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+ {
+ /* do not have a thread per connection, process all connections now */
+ prev = daemon->connections_tail;
+ while (NULL != (pos = prev))
{
- /* do not have a thread per connection, process all connections now */
- prev = daemon->connections_tail;
- while (NULL != (pos = prev))
- {
- prev = pos->prev;
- ds = pos->socket_fd;
- if (MHD_INVALID_SOCKET == ds)
- continue;
- call_handlers (pos,
- FD_ISSET (ds,
- read_fd_set),
- FD_ISSET (ds,
- write_fd_set),
- FD_ISSET (ds,
- except_fd_set));
- }
+ prev = pos->prev;
+ ds = pos->socket_fd;
+ if (MHD_INVALID_SOCKET == ds)
+ continue;
+ call_handlers (pos,
+ FD_ISSET (ds,
+ read_fd_set),
+ FD_ISSET (ds,
+ write_fd_set),
+ FD_ISSET (ds,
+ except_fd_set));
}
+ }
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
/* handle upgraded HTTPS connections */
for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
+ {
+ urhn = urh->prev;
+ /* update urh state based on select() output */
+ urh_from_fdset (urh,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set);
+ /* call generic forwarding function for passing data */
+ process_urh (urh);
+ /* Finished forwarding? */
+ if ( (0 == urh->in_buffer_size) &&
+ (0 == urh->out_buffer_size) &&
+ (0 == urh->in_buffer_used) &&
+ (0 == urh->out_buffer_used) )
{
- urhn = urh->prev;
- /* update urh state based on select() output */
- urh_from_fdset (urh,
- read_fd_set,
- write_fd_set,
- except_fd_set);
- /* call generic forwarding function for passing data */
- process_urh (urh);
- /* Finished forwarding? */
- if ( (0 == urh->in_buffer_size) &&
- (0 == urh->out_buffer_size) &&
- (0 == urh->in_buffer_used) &&
- (0 == urh->out_buffer_used) )
- {
- MHD_connection_finish_forward_ (urh->connection);
- urh->clean_ready = true;
- /* Resuming will move connection to cleanup list. */
- MHD_resume_connection(urh->connection);
- }
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* Resuming will move connection to cleanup list. */
+ MHD_resume_connection (urh->connection);
}
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
MHD_cleanup_connections (daemon);
return MHD_YES;
@@ -3439,8 +4000,8 @@
/**
* Run webserver operations. This method should be called by clients
- * in combination with #MHD_get_fdset if the client-controlled select
- * method is used.
+ * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
+ * client-controlled select method is used.
*
* You can use this function instead of #MHD_run if you called
* `select()` on the result from #MHD_get_fdset. File descriptors in
@@ -3459,46 +4020,49 @@
* @return #MHD_NO on serious errors, #MHD_YES on success
* @ingroup event
*/
-int
+enum MHD_Result
MHD_run_from_select (struct MHD_Daemon *daemon,
const fd_set *read_fd_set,
const fd_set *write_fd_set,
const fd_set *except_fd_set)
{
fd_set es;
- if (0 != (daemon->options &
- (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL)) )
+ if (0 != (daemon->options
+ & (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL)) )
return MHD_NO;
- if (NULL == read_fd_set || NULL == write_fd_set)
+ if ((NULL == read_fd_set) || (NULL == write_fd_set))
return MHD_NO;
if (NULL == except_fd_set)
- { /* Workaround to maintain backward compatibility. */
+ { /* Workaround to maintain backward compatibility. */
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD_run_from_select() called with except_fd_set "
- "set to NULL. Such behavior is deprecated.\n"));
+ MHD_DLOG (daemon,
+ _ ("MHD_run_from_select() called with except_fd_set "
+ "set to NULL. Such behavior is deprecated.\n"));
#endif
- FD_ZERO (&es);
- except_fd_set = &es;
- }
+ FD_ZERO (&es);
+ except_fd_set = &es;
+ }
if (0 != (daemon->options & MHD_USE_EPOLL))
- {
+ {
#ifdef EPOLL_SUPPORT
- int ret;
- ret = MHD_epoll (daemon, MHD_NO);
- MHD_cleanup_connections (daemon);
- return ret;
+ enum MHD_Result ret = MHD_epoll (daemon,
+ 0);
+
+ MHD_cleanup_connections (daemon);
+ return ret;
#else /* ! EPOLL_SUPPORT */
- return MHD_NO;
+ return MHD_NO;
#endif /* ! EPOLL_SUPPORT */
- }
+ }
/* Resuming external connections when using an extern mainloop */
if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
resume_suspended_connections (daemon);
- return internal_run_from_select (daemon, read_fd_set,
- write_fd_set, except_fd_set);
+ return internal_run_from_select (daemon,
+ read_fd_set,
+ write_fd_set,
+ except_fd_set);
}
@@ -3507,12 +4071,14 @@
* and then #internal_run_from_select with the result.
*
* @param daemon daemon to run select() loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_select (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
int num_ready;
fd_set rs;
@@ -3521,7 +4087,6 @@
MHD_socket maxsock;
struct timeval timeout;
struct timeval *tv;
- MHD_UNSIGNED_LONG_LONG ltimeout;
int err_state;
MHD_socket ls;
@@ -3535,76 +4100,79 @@
maxsock = MHD_INVALID_SOCKET;
err_state = MHD_NO;
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
- (MHD_YES == resume_suspended_connections (daemon)) &&
+ (MHD_NO != resume_suspended_connections (daemon)) &&
(0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
- may_block = MHD_NO;
+ millisec = 0;
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+ {
+ /* single-threaded, go over everything */
+ if (MHD_NO ==
+ internal_get_fdset2 (daemon,
+ &rs,
+ &ws,
+ &es,
+ &maxsock,
+ FD_SETSIZE))
{
- /* single-threaded, go over everything */
- if (MHD_NO ==
- internal_get_fdset2 (daemon,
- &rs,
- &ws,
- &es,
- &maxsock,
- FD_SETSIZE))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Could not obtain daemon fdsets"));
+ MHD_DLOG (daemon,
+ _ ("Could not obtain daemon fdsets.\n"));
#endif
- err_state = MHD_YES;
- }
+ err_state = MHD_YES;
}
+ }
else
+ {
+ /* accept only, have one thread per connection */
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+ (! daemon->was_quiesced) &&
+ (! MHD_add_to_fd_set_ (ls,
+ &rs,
+ &maxsock,
+ FD_SETSIZE)) )
{
- /* accept only, have one thread per connection */
- if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
- (! daemon->was_quiesced) &&
- (! MHD_add_to_fd_set_ (ls,
- &rs,
- &maxsock,
- FD_SETSIZE)) )
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Could not add listen socket to fdset"));
+ MHD_DLOG (daemon,
+ _ ("Could not add listen socket to fdset.\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
}
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
+ }
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
(! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
&rs,
&maxsock,
FD_SETSIZE)) )
- {
+ {
#if defined(MHD_WINSOCK_SOCKETS)
- /* fdset limit reached, new connections
- cannot be handled. Remove listen socket FD
- from fdset and retry to add ITC FD. */
- if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
- (! daemon->was_quiesced) )
- {
- FD_CLR (ls,
- &rs);
- if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc),
- &rs,
- &maxsock,
- FD_SETSIZE))
- {
+ /* fdset limit reached, new connections
+ cannot be handled. Remove listen socket FD
+ from fdset and retry to add ITC FD. */
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+ (! daemon->was_quiesced) )
+ {
+ FD_CLR (ls,
+ &rs);
+ if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
+ &rs,
+ &maxsock,
+ FD_SETSIZE))
+ {
#endif /* MHD_WINSOCK_SOCKETS */
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Could not add control inter-thread communication channel FD to fdset"));
+ MHD_DLOG (daemon,
+ _ (
+ "Could not add control inter-thread communication channel FD to fdset.\n"));
#endif
- err_state = MHD_YES;
+ err_state = MHD_YES;
#if defined(MHD_WINSOCK_SOCKETS)
- }
- }
+ }
+}
+
+
#endif /* MHD_WINSOCK_SOCKETS */
- }
+ }
/* Stop listening if we are at the configured connection limit */
/* If we're at the connection limit, no point in really
accepting new connections; however, make sure we do not miss
@@ -3612,33 +4180,55 @@
only do this optimization if we have a signaling ITC in
place. */
if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
- (MHD_ITC_IS_VALID_(daemon->itc)) &&
+ (MHD_ITC_IS_VALID_ (daemon->itc)) &&
( (daemon->connections == daemon->connection_limit) ||
(daemon->at_limit) ) )
- {
- FD_CLR (ls,
- &rs);
- }
+ {
+ FD_CLR (ls,
+ &rs);
+ }
+
+ if (MHD_NO != err_state)
+ millisec = 0;
tv = NULL;
- if (MHD_YES == err_state)
- may_block = MHD_NO;
- if (MHD_NO == may_block)
+ if (0 == millisec)
+ {
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ tv = &timeout;
+ }
+ else
+ {
+ MHD_UNSIGNED_LONG_LONG ltimeout;
+
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (MHD_NO != MHD_get_timeout (daemon, <imeout)) )
{
- timeout.tv_usec = 0;
- timeout.tv_sec = 0;
- tv = &timeout;
+ tv = &timeout; /* have timeout value */
+ if ( (0 < millisec) &&
+ (ltimeout > (MHD_UNSIGNED_LONG_LONG) millisec) )
+ ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
}
- else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (MHD_YES == MHD_get_timeout (daemon, <imeout)) )
+ else if (0 < millisec)
{
- /* ltimeout is in ms */
- timeout.tv_usec = (ltimeout % 1000) * 1000;
+ tv = &timeout; /* have timeout value */
+ ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
+ }
+
+ if (NULL != tv)
+ { /* have timeout value */
if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
+ {
timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
+ timeout.tv_usec = 0;
+ }
else
- timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
- tv = &timeout;
+ {
+ timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
+ timeout.tv_usec = (ltimeout % 1000) * 1000;
+ }
}
+ }
num_ready = MHD_SYS_select_ (maxsock + 1,
&rs,
&ws,
@@ -3647,21 +4237,21 @@
if (daemon->shutdown)
return MHD_NO;
if (num_ready < 0)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_(err))
- return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("select failed: %s\n"),
- MHD_socket_strerr_ (err));
+ MHD_DLOG (daemon,
+ _ ("select failed: %s\n"),
+ MHD_socket_strerr_ (err));
#endif
- return MHD_NO;
- }
- if (MHD_YES == internal_run_from_select (daemon,
- &rs,
- &ws,
- &es))
+ return MHD_NO;
+ }
+ if (MHD_NO != internal_run_from_select (daemon,
+ &rs,
+ &ws,
+ &es))
return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
return MHD_NO;
}
@@ -3673,12 +4263,14 @@
* socket using poll().
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_poll_all (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
unsigned int num_connections;
struct MHD_Connection *pos;
@@ -3689,8 +4281,8 @@
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
- (MHD_YES == resume_suspended_connections (daemon)) )
- may_block = MHD_NO;
+ (MHD_NO != resume_suspended_connections (daemon)) )
+ millisec = 0;
/* count number of connections and thus determine poll set size */
num_connections = 0;
@@ -3701,7 +4293,6 @@
num_connections += 2;
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
{
- MHD_UNSIGNED_LONG_LONG ltimeout;
unsigned int i;
int timeout;
unsigned int poll_server;
@@ -3710,102 +4301,94 @@
struct pollfd *p;
MHD_socket ls;
- p = MHD_calloc_ ((2 + num_connections), sizeof (struct pollfd));
+ p = MHD_calloc_ ((2 + (size_t) num_connections),
+ sizeof (struct pollfd));
if (NULL == p)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error allocating memory: %s\n"),
- MHD_strerror_(errno));
+ MHD_DLOG (daemon,
+ _ ("Error allocating memory: %s\n"),
+ MHD_strerror_ (errno));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
poll_server = 0;
poll_listen = -1;
if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
(! daemon->was_quiesced) &&
- (daemon->connections < daemon->connection_limit) &&
+ (daemon->connections < daemon->connection_limit) &&
(! daemon->at_limit) )
- {
- /* only listen if we are not at the connection limit */
- p[poll_server].fd = ls;
- p[poll_server].events = POLLIN;
- p[poll_server].revents = 0;
- poll_listen = (int) poll_server;
- poll_server++;
- }
+ {
+ /* only listen if we are not at the connection limit */
+ p[poll_server].fd = ls;
+ p[poll_server].events = POLLIN;
+ p[poll_server].revents = 0;
+ poll_listen = (int) poll_server;
+ poll_server++;
+ }
poll_itc_idx = -1;
- if (MHD_ITC_IS_VALID_(daemon->itc))
- {
- p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
- p[poll_server].events = POLLIN;
- p[poll_server].revents = 0;
- poll_itc_idx = (int) poll_server;
- poll_server++;
- }
- if (may_block == MHD_NO)
- timeout = 0;
- else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
- (MHD_YES != MHD_get_timeout (daemon,
- <imeout)) )
- timeout = -1;
- else
- timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[poll_server].events = POLLIN;
+ p[poll_server].revents = 0;
+ poll_itc_idx = (int) poll_server;
+ poll_server++;
+ }
+
+ timeout = get_timeout_millisec_ (daemon, millisec);
i = 0;
for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
+ {
+ p[poll_server + i].fd = pos->socket_fd;
+ switch (pos->event_loop_info)
{
- p[poll_server+i].fd = pos->socket_fd;
- switch (pos->event_loop_info)
- {
- case MHD_EVENT_LOOP_INFO_READ:
- p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_WRITE:
- p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_BLOCK:
- p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
- break;
- case MHD_EVENT_LOOP_INFO_CLEANUP:
- timeout = 0; /* clean up "pos" immediately */
- break;
- }
- i++;
+ case MHD_EVENT_LOOP_INFO_READ:
+ p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ timeout = 0; /* clean up "pos" immediately */
+ break;
}
+ i++;
+ }
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
- {
- urh_to_pollfd(urh, &(p[poll_server+i]));
- i += 2;
- }
+ {
+ urh_to_pollfd (urh, &(p[poll_server + i]));
+ i += 2;
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
if (0 == poll_server + num_connections)
+ {
+ free (p);
+ return MHD_YES;
+ }
+ if (MHD_sys_poll_ (p,
+ poll_server + num_connections,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
{
- free(p);
- return MHD_YES;
- }
- if (MHD_sys_poll_(p,
- poll_server + num_connections,
- timeout) < 0)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err))
- {
- free(p);
+ free (p);
return MHD_YES;
}
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("poll failed: %s\n"),
- MHD_socket_strerr_ (err));
+ MHD_DLOG (daemon,
+ _ ("poll failed: %s\n"),
+ MHD_socket_strerr_ (err));
#endif
- free(p);
- return MHD_NO;
- }
-
- /* Reset. New value will be set when connections are processed. */
- daemon->data_already_pending = false;
+ free (p);
+ return MHD_NO;
+ }
/* handle ITC FD */
/* do it before any other processing so
@@ -3816,66 +4399,77 @@
/* handle shutdown */
if (daemon->shutdown)
- {
- free(p);
- return MHD_NO;
- }
+ {
+ free (p);
+ return MHD_NO;
+ }
+
+ /* Process externally added connection if any */
+ if (daemon->have_new)
+ new_connections_list_process_ (daemon);
+
+ /* handle 'listen' FD */
+ if ( (-1 != poll_listen) &&
+ (0 != (p[poll_listen].revents & POLLIN)) )
+ (void) MHD_accept_connection (daemon);
+
+ /* Reset. New value will be set when connections are processed. */
+ daemon->data_already_pending = false;
+
i = 0;
prev = daemon->connections_tail;
while (NULL != (pos = prev))
- {
- prev = pos->prev;
- /* first, sanity checks */
- if (i >= num_connections)
- break; /* connection list changed somehow, retry later ... */
- if (p[poll_server+i].fd != pos->socket_fd)
- continue; /* fd mismatch, something else happened, retry later ... */
- call_handlers (pos,
- 0 != (p[poll_server+i].revents & POLLIN),
- 0 != (p[poll_server+i].revents & POLLOUT),
- 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
- i++;
- }
+ {
+ prev = pos->prev;
+ /* first, sanity checks */
+ if (i >= num_connections)
+ break; /* connection list changed somehow, retry later ... */
+ if (p[poll_server + i].fd != pos->socket_fd)
+ continue; /* fd mismatch, something else happened, retry later ... */
+ call_handlers (pos,
+ 0 != (p[poll_server + i].revents & POLLIN),
+ 0 != (p[poll_server + i].revents & POLLOUT),
+ 0 != (p[poll_server + i].revents
+ & MHD_POLL_REVENTS_ERR_DISC));
+ i++;
+ }
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
- {
- if (i >= num_connections)
- break; /* connection list changed somehow, retry later ... */
+ {
+ if (i >= num_connections)
+ break; /* connection list changed somehow, retry later ... */
- /* Get next connection here as connection can be removed
- * from 'daemon->urh_head' list. */
- urhn = urh->prev;
- /* Check for fd mismatch. FIXME: required for safety? */
- if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
- (p[poll_server+i+1].fd != urh->mhd.socket))
- break;
- urh_from_pollfd(urh, &(p[poll_server+i]));
- i += 2;
- process_urh (urh);
- /* Finished forwarding? */
- if ( (0 == urh->in_buffer_size) &&
- (0 == urh->out_buffer_size) &&
- (0 == urh->in_buffer_used) &&
- (0 == urh->out_buffer_used) )
- {
- /* MHD_connection_finish_forward_() will remove connection from
- * 'daemon->urh_head' list. */
- MHD_connection_finish_forward_ (urh->connection);
- urh->clean_ready = true;
- /* If 'urh->was_closed' already was set to true, connection will be
- * moved immediately to cleanup list. Otherwise connection
- * will stay in suspended list until 'urh' will be marked
- * with 'was_closed' by application. */
- MHD_resume_connection(urh->connection);
- }
+ /* Get next connection here as connection can be removed
+ * from 'daemon->urh_head' list. */
+ urhn = urh->prev;
+ /* Check for fd mismatch. FIXME: required for safety? */
+ if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
+ (p[poll_server + i + 1].fd != urh->mhd.socket))
+ break;
+ urh_from_pollfd (urh,
+ &p[poll_server + i]);
+ i += 2;
+ process_urh (urh);
+ /* Finished forwarding? */
+ if ( (0 == urh->in_buffer_size) &&
+ (0 == urh->out_buffer_size) &&
+ (0 == urh->in_buffer_used) &&
+ (0 == urh->out_buffer_used) )
+ {
+ /* MHD_connection_finish_forward_() will remove connection from
+ * 'daemon->urh_head' list. */
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* If 'urh->was_closed' already was set to true, connection will be
+ * moved immediately to cleanup list. Otherwise connection
+ * will stay in suspended list until 'urh' will be marked
+ * with 'was_closed' by application. */
+ MHD_resume_connection (urh->connection);
}
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
- /* handle 'listen' FD */
- if ( (-1 != poll_listen) &&
- (0 != (p[poll_listen].revents & POLLIN)) )
- (void) MHD_accept_connection (daemon);
- free(p);
+ free (p);
}
return MHD_YES;
}
@@ -3888,9 +4482,9 @@
* @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_poll_listen_socket (struct MHD_Daemon *daemon,
- int may_block)
+ int may_block)
{
struct pollfd p[2];
int timeout;
@@ -3908,24 +4502,24 @@
if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
(! daemon->was_quiesced) )
- {
- p[poll_count].fd = ls;
- p[poll_count].events = POLLIN;
- p[poll_count].revents = 0;
- poll_listen = poll_count;
- poll_count++;
- }
- if (MHD_ITC_IS_VALID_(daemon->itc))
- {
- p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
- p[poll_count].events = POLLIN;
- p[poll_count].revents = 0;
- poll_itc_idx = poll_count;
- poll_count++;
- }
+ {
+ p[poll_count].fd = ls;
+ p[poll_count].events = POLLIN;
+ p[poll_count].revents = 0;
+ poll_listen = poll_count;
+ poll_count++;
+ }
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
+ p[poll_count].events = POLLIN;
+ p[poll_count].revents = 0;
+ poll_itc_idx = poll_count;
+ poll_count++;
+ }
if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
- (void)resume_suspended_connections (daemon);
+ (void) resume_suspended_connections (daemon);
if (MHD_NO == may_block)
timeout = 0;
@@ -3933,21 +4527,21 @@
timeout = -1;
if (0 == poll_count)
return MHD_YES;
- if (MHD_sys_poll_(p,
- poll_count,
- timeout) < 0)
- {
- const int err = MHD_socket_get_error_ ();
+ if (MHD_sys_poll_ (p,
+ poll_count,
+ timeout) < 0)
+ {
+ const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err))
- return MHD_YES;
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_YES;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("poll failed: %s\n"),
- MHD_socket_strerr_ (err));
+ MHD_DLOG (daemon,
+ _ ("poll failed: %s\n"),
+ MHD_socket_strerr_ (err));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
if ( (-1 != poll_itc_idx) &&
(0 != (p[poll_itc_idx].revents & POLLIN)) )
MHD_itc_clear_ (daemon->itc);
@@ -3955,11 +4549,18 @@
/* handle shutdown */
if (daemon->shutdown)
return MHD_NO;
+
+ /* Process externally added connection if any */
+ if (daemon->have_new)
+ new_connections_list_process_ (daemon);
+
if ( (-1 != poll_listen) &&
(0 != (p[poll_listen].revents & POLLIN)) )
(void) MHD_accept_connection (daemon);
return MHD_YES;
}
+
+
#endif
@@ -3970,19 +4571,21 @@
* @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_poll (struct MHD_Daemon *daemon,
- int may_block)
+ int may_block)
{
#ifdef HAVE_POLL
if (daemon->shutdown)
return MHD_NO;
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
return MHD_poll_all (daemon,
- may_block);
+ may_block ? -1 : 0);
return MHD_poll_listen_socket (daemon,
may_block);
#else
+ (void) daemon;
+ (void) may_block;
return MHD_NO;
#endif
}
@@ -4011,39 +4614,34 @@
* 'false' otherwise
*/
static bool
-is_urh_ready(struct MHD_UpgradeResponseHandle * const urh)
+is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
{
- const struct MHD_Connection * const connection = urh->connection;
+ const struct MHD_Connection *const connection = urh->connection;
if ( (0 == urh->in_buffer_size) &&
(0 == urh->out_buffer_size) &&
(0 == urh->in_buffer_used) &&
(0 == urh->out_buffer_used) )
return false;
-
if (connection->daemon->shutdown)
return true;
-
if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
(connection->tls_read_ready) ) &&
(urh->in_buffer_used < urh->in_buffer_size) )
return true;
-
if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
(urh->out_buffer_used < urh->out_buffer_size) )
return true;
-
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
(urh->out_buffer_used > 0) )
return true;
-
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
- (urh->in_buffer_used > 0) )
+ (urh->in_buffer_used > 0) )
return true;
-
return false;
}
+
/**
* Do epoll()-based processing for TLS connections that have been
* upgraded. This requires a separate epoll() invocation as we
@@ -4052,139 +4650,154 @@
* @remark To be called only from thread that process
* daemon's select()/poll()/etc.
*/
-static int
+static enum MHD_Result
run_epoll_for_upgrade (struct MHD_Daemon *daemon)
{
struct epoll_event events[MAX_EVENTS];
int num_events;
- struct MHD_UpgradeResponseHandle * pos;
- struct MHD_UpgradeResponseHandle * prev;
+ struct MHD_UpgradeResponseHandle *pos;
+ struct MHD_UpgradeResponseHandle *prev;
+
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
num_events = MAX_EVENTS;
- while (MAX_EVENTS == num_events)
+ while (0 != num_events)
+ {
+ unsigned int i;
+ /* update event masks */
+ num_events = epoll_wait (daemon->epoll_upgrade_fd,
+ events,
+ MAX_EVENTS,
+ 0);
+ if (-1 == num_events)
{
- unsigned int i;
- /* update event masks */
- num_events = epoll_wait (daemon->epoll_upgrade_fd,
- events,
- MAX_EVENTS,
- 0);
- if (-1 == num_events)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err))
- return MHD_YES;
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_YES;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_wait failed: %s\n"),
- MHD_socket_strerr_ (err));
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_wait failed: %s\n"),
+ MHD_socket_strerr_ (err));
#endif
- return MHD_NO;
- }
- for (i = 0; i < (unsigned int) num_events; i++)
- {
- struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
- struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
- bool new_err_state = false;
+ return MHD_NO;
+ }
+ for (i = 0; i < (unsigned int) num_events; i++)
+ {
+ struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
+ struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
+ bool new_err_state = false;
- if (urh->clean_ready)
- continue;
+ if (urh->clean_ready)
+ continue;
+
+ /* Update ueh state based on what is ready according to epoll() */
+ if (0 != (events[i].events & EPOLLIN))
+ {
+ ueh->celi |= MHD_EPOLL_STATE_READ_READY;
+ }
+ if (0 != (events[i].events & EPOLLOUT))
+ {
+ ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
+ }
+ if (0 != (events[i].events & EPOLLHUP))
+ {
+ ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
+ }
- /* Update ueh state based on what is ready according to epoll() */
- if (0 != (events[i].events & EPOLLIN))
- ueh->celi |= MHD_EPOLL_STATE_READ_READY;
- if (0 != (events[i].events & EPOLLOUT))
- ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
- if (0 != (events[i].events & EPOLLHUP))
- ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
-
- if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
- (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
- {
- /* Process new error state only one time
- * and avoid continuously marking this connection
- * as 'ready'. */
- ueh->celi |= MHD_EPOLL_STATE_ERROR;
- new_err_state = true;
- }
-
- if (! urh->in_eready_list)
- {
- if (new_err_state ||
- is_urh_ready(urh))
- {
- EDLL_insert (daemon->eready_urh_head,
- daemon->eready_urh_tail,
- urh);
- urh->in_eready_list = true;
- }
- }
+ if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
+ (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
+ {
+ /* Process new error state only one time and avoid continuously
+ * marking this connection as 'ready'. */
+ ueh->celi |= MHD_EPOLL_STATE_ERROR;
+ new_err_state = true;
+ }
+ if (! urh->in_eready_list)
+ {
+ if (new_err_state ||
+ is_urh_ready (urh))
+ {
+ EDLL_insert (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ urh);
+ urh->in_eready_list = true;
}
+ }
}
+ }
prev = daemon->eready_urh_tail;
while (NULL != (pos = prev))
- {
- prev = pos->prevE;
- process_urh (pos);
- if (! is_urh_ready(pos))
- {
- EDLL_remove (daemon->eready_urh_head,
- daemon->eready_urh_tail,
- pos);
- pos->in_eready_list = false;
- }
- /* Finished forwarding? */
- if ( (0 == pos->in_buffer_size) &&
- (0 == pos->out_buffer_size) &&
- (0 == pos->in_buffer_used) &&
- (0 == pos->out_buffer_used) )
- {
- MHD_connection_finish_forward_ (pos->connection);
- pos->clean_ready = true;
- /* If 'pos->was_closed' already was set to true, connection
- * will be moved immediately to cleanup list. Otherwise
- * connection will stay in suspended list until 'pos' will
- * be marked with 'was_closed' by application. */
- MHD_resume_connection(pos->connection);
- }
+ {
+ prev = pos->prevE;
+ process_urh (pos);
+ if (! is_urh_ready (pos))
+ {
+ EDLL_remove (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ pos);
+ pos->in_eready_list = false;
+ }
+ /* Finished forwarding? */
+ if ( (0 == pos->in_buffer_size) &&
+ (0 == pos->out_buffer_size) &&
+ (0 == pos->in_buffer_used) &&
+ (0 == pos->out_buffer_used) )
+ {
+ MHD_connection_finish_forward_ (pos->connection);
+ pos->clean_ready = true;
+ /* If 'pos->was_closed' already was set to true, connection
+ * will be moved immediately to cleanup list. Otherwise
+ * connection will stay in suspended list until 'pos' will
+ * be marked with 'was_closed' by application. */
+ MHD_resume_connection (pos->connection);
}
+ }
return MHD_YES;
}
+
+
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
/**
* Pointer-marker to distinguish ITC slot in epoll sets.
*/
-static const char * const epoll_itc_marker = "itc_marker";
+static const char *const epoll_itc_marker = "itc_marker";
+
/**
- * Do epoll()-based processing (this function is allowed to
- * block if @a may_block is set to #MHD_YES).
+ * Do epoll()-based processing.
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
-static int
+static enum MHD_Result
MHD_epoll (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- static const char * const upgrade_marker = "upgrade_ptr";
+ static const char *const upgrade_marker = "upgrade_ptr";
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
struct MHD_Connection *pos;
struct MHD_Connection *prev;
struct epoll_event events[MAX_EVENTS];
struct epoll_event event;
int timeout_ms;
- MHD_UNSIGNED_LONG_LONG timeout_ll;
int num_events;
unsigned int i;
MHD_socket ls;
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- int run_upgraded = MHD_NO;
+ bool run_upgraded = false;
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+ bool need_to_accept;
if (-1 == daemon->epoll_fd)
return MHD_NO; /* we're down! */
@@ -4195,240 +4808,206 @@
(daemon->connections < daemon->connection_limit) &&
(! daemon->listen_socket_in_epoll) &&
(! daemon->at_limit) )
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = daemon;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ ls,
+ &event))
{
- event.events = EPOLLIN;
- event.data.ptr = daemon;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- ls,
- &event))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- return MHD_NO;
- }
- daemon->listen_socket_in_epoll = true;
+ return MHD_NO;
}
+ daemon->listen_socket_in_epoll = true;
+ }
if ( (daemon->was_quiesced) &&
(daemon->listen_socket_in_epoll) )
{
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- ls,
- NULL))
- MHD_PANIC ("Failed to remove listen FD from epoll set\n");
+ if ( (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ls,
+ NULL)) &&
+ (ENOENT != errno) ) /* ENOENT can happen due to race with
+ #MHD_quiesce_daemon() */
+ MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
daemon->listen_socket_in_epoll = false;
}
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if ( (! daemon->upgrade_fd_in_epoll) &&
- (-1 != daemon->epoll_upgrade_fd) )
+ if ( ( (! daemon->upgrade_fd_in_epoll) &&
+ (-1 != daemon->epoll_upgrade_fd) ) )
+ {
+ event.events = EPOLLIN | EPOLLOUT;
+ event.data.ptr = (void *) upgrade_marker;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ daemon->epoll_upgrade_fd,
+ &event))
{
- event.events = EPOLLIN | EPOLLOUT;
- event.data.ptr = (void *) upgrade_marker;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- daemon->epoll_upgrade_fd,
- &event))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- return MHD_NO;
- }
- daemon->upgrade_fd_in_epoll = true;
+ return MHD_NO;
}
+ daemon->upgrade_fd_in_epoll = true;
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
if ( (daemon->listen_socket_in_epoll) &&
( (daemon->connections == daemon->connection_limit) ||
(daemon->at_limit) ||
(daemon->was_quiesced) ) )
- {
- /* we're at the connection limit, disable listen socket
- for event loop for now */
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- ls,
- NULL))
- MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
- daemon->listen_socket_in_epoll = false;
- }
+ {
+ /* we're at the connection limit, disable listen socket
+ for event loop for now */
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ls,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
+ daemon->listen_socket_in_epoll = false;
+ }
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
- (MHD_YES == resume_suspended_connections (daemon)) )
- may_block = MHD_NO;
+ (MHD_NO != resume_suspended_connections (daemon)) )
+ millisec = 0;
- if (MHD_YES == may_block)
- {
- if (MHD_YES == MHD_get_timeout (daemon,
- &timeout_ll))
- {
- if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
- timeout_ms = INT_MAX;
- else
- timeout_ms = (int) timeout_ll;
- }
- else
- timeout_ms = -1;
- }
- else
- timeout_ms = 0;
+ timeout_ms = get_timeout_millisec_ (daemon, millisec);
/* Reset. New value will be set when connections are processed. */
/* Note: Used mostly for uniformity here as same situation is
* signaled in epoll mode by non-empty eready DLL. */
daemon->data_already_pending = false;
+ need_to_accept = false;
/* drain 'epoll' event queue; need to iterate as we get at most
MAX_EVENTS in one system call here; in practice this should
pretty much mean only one round, but better an extra loop here
than unfair behavior... */
num_events = MAX_EVENTS;
while (MAX_EVENTS == num_events)
+ {
+ /* update event masks */
+ num_events = epoll_wait (daemon->epoll_fd,
+ events,
+ MAX_EVENTS,
+ timeout_ms);
+ if (-1 == num_events)
{
- /* update event masks */
- num_events = epoll_wait (daemon->epoll_fd,
- events,
- MAX_EVENTS,
- timeout_ms);
- if (-1 == num_events)
- {
- const int err = MHD_socket_get_error_ ();
- if (MHD_SCKT_ERR_IS_EINTR_ (err))
- return MHD_YES;
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_YES;
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_wait failed: %s\n"),
- MHD_socket_strerr_ (err));
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_wait failed: %s\n"),
+ MHD_socket_strerr_ (err));
#endif
- return MHD_NO;
- }
- for (i=0;i<(unsigned int) num_events;i++)
- {
- /* First, check for the values of `ptr` that would indicate
- that this event is not about a normal connection. */
- if (NULL == events[i].data.ptr)
- continue; /* shutdown signal! */
-#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if (upgrade_marker == events[i].data.ptr)
- {
- /* activity on an upgraded connection, we process
- those in a separate epoll() */
- run_upgraded = MHD_YES;
- continue;
- }
-#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
- if (epoll_itc_marker == events[i].data.ptr)
- {
- /* It's OK to clear ITC here as all external
- conditions will be processed later. */
- MHD_itc_clear_ (daemon->itc);
- continue;
- }
- if (daemon == events[i].data.ptr)
- {
- /* Check for error conditions on listen socket. */
- /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
- if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
- {
- unsigned int series_length = 0;
- /* Run 'accept' until it fails or daemon at limit of connections.
- * Do not accept more then 10 connections at once. The rest will
- * be accepted on next turn (level trigger is used for listen
- * socket). */
- while ( (MHD_YES == MHD_accept_connection (daemon)) &&
- (series_length < 10) &&
- (daemon->connections < daemon->connection_limit) &&
- (! daemon->at_limit) )
- series_length++;
- }
- continue;
- }
- /* this is an event relating to a 'normal' connection,
- remember the event and if appropriate mark the
- connection as 'eready'. */
- pos = events[i].data.ptr;
- /* normal processing: update read/write data */
- if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
- {
- pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
- if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- }
- else
- {
- if (0 != (events[i].events & EPOLLIN))
- {
- pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
- if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
- (pos->read_buffer_size > pos->read_buffer_offset) ) &&
- (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- }
- if (0 != (events[i].events & EPOLLOUT))
- {
- pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
- if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
- (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- }
- }
- }
+ return MHD_NO;
}
-
+ for (i = 0; i<(unsigned int) num_events; i++)
+ {
+ /* First, check for the values of `ptr` that would indicate
+ that this event is not about a normal connection. */
+ if (NULL == events[i].data.ptr)
+ continue; /* shutdown signal! */
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if (MHD_YES == run_upgraded)
- run_epoll_for_upgrade (daemon);
+ if (upgrade_marker == events[i].data.ptr)
+ {
+ /* activity on an upgraded connection, we process
+ those in a separate epoll() */
+ run_upgraded = true;
+ continue;
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-
- /* process events for connections */
- prev = daemon->eready_tail;
- while (NULL != (pos = prev))
- {
- prev = pos->prevE;
- call_handlers (pos,
- 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
- 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
- 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
- if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
- (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
+ if (epoll_itc_marker == events[i].data.ptr)
+ {
+ /* It's OK to clear ITC here as all external
+ conditions will be processed later. */
+ MHD_itc_clear_ (daemon->itc);
+ continue;
+ }
+ if (daemon == events[i].data.ptr)
+ {
+ /* Check for error conditions on listen socket. */
+ /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
+ if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
+ need_to_accept = true;
+ continue;
+ }
+ /* this is an event relating to a 'normal' connection,
+ remember the event and if appropriate mark the
+ connection as 'eready'. */
+ pos = events[i].data.ptr;
+ /* normal processing: update read/write data */
+ if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
+ if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
{
- if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
- 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
- (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info &&
- 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
- MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info)
- {
- EDLL_remove (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
}
+ }
+ else
+ {
+ if (0 != (events[i].events & EPOLLIN))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
+ if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
+ (pos->read_buffer_size > pos->read_buffer_offset) ) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ if (0 != (events[i].events & EPOLLOUT))
+ {
+ pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
+ if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ }
+ }
}
+ }
+
+ /* Process externally added connection if any */
+ if (daemon->have_new)
+ new_connections_list_process_ (daemon);
+
+ if (need_to_accept)
+ {
+ unsigned int series_length = 0;
+
+ /* Run 'accept' until it fails or daemon at limit of connections.
+ * Do not accept more then 10 connections at once. The rest will
+ * be accepted on next turn (level trigger is used for listen
+ * socket). */
+ while ( (MHD_NO != MHD_accept_connection (daemon)) &&
+ (series_length < 10) &&
+ (daemon->connections < daemon->connection_limit) &&
+ (! daemon->at_limit) )
+ series_length++;
+ }
- /* Finally, handle timed-out connections; we need to do this here
- as the epoll mechanism won't call the 'idle_handler' on everything,
+ /* Handle timed-out connections; we need to do this here
+ as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
as the other event loops do. As timeouts do not get an explicit
event, we need to find those connections that might have timed out
here.
@@ -4437,31 +5016,67 @@
do not bother to sort that (presumably very short) list. */
prev = daemon->manual_timeout_tail;
while (NULL != (pos = prev))
- {
- prev = pos->prevX;
- pos->idle_handler (pos);
- }
+ {
+ prev = pos->prevX;
+ MHD_connection_handle_idle (pos);
+ }
/* Connections with the default timeout are sorted by prepending
them to the head of the list whenever we touch the connection;
thus it suffices to iterate from the tail until the first
connection is NOT timed out */
prev = daemon->normal_timeout_tail;
while (NULL != (pos = prev))
- {
- prev = pos->prevX;
- pos->idle_handler (pos);
- if (MHD_CONNECTION_CLOSED != pos->state)
- break; /* sorted by timeout, no need to visit the rest! */
+ {
+ prev = pos->prevX;
+ MHD_connection_handle_idle (pos);
+ if (MHD_CONNECTION_CLOSED != pos->state)
+ break; /* sorted by timeout, no need to visit the rest! */
+ }
+
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ if (run_upgraded || (NULL != daemon->eready_urh_head))
+ run_epoll_for_upgrade (daemon);
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+ /* process events for connections */
+ prev = daemon->eready_tail;
+ while (NULL != (pos = prev))
+ {
+ prev = pos->prevE;
+ call_handlers (pos,
+ 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
+ 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
+ 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
+ if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
+ (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
+ | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
+ {
+ if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
+ ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
+ (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
+ (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) )
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
}
+ }
+
return MHD_YES;
}
+
+
#endif
/**
* Run webserver operations (without blocking unless in client
* callbacks). This method should be called by clients in combination
- * with #MHD_get_fdset if the client-controlled select method is used.
+ * with #MHD_get_fdset if the client-controlled select method is used and
+ * #MHD_get_timeout().
*
* This function is a convenience method, which is useful if the
* fd_sets from #MHD_get_fdset were not directly passed to `select()`;
@@ -4477,30 +5092,81 @@
* options for this call.
* @ingroup event
*/
-int
+enum MHD_Result
MHD_run (struct MHD_Daemon *daemon)
{
if ( (daemon->shutdown) ||
(0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
return MHD_NO;
- if (0 != (daemon->options & MHD_USE_POLL))
+
+ (void) MHD_run_wait (daemon, 0);
+ return MHD_YES;
+}
+
+
+/**
+ * Run websever operation with possible blocking.
+ * This function do the following: waits for any network event not more than
+ * specified number of milliseconds, processes all incoming and outgoing
+ * data, processes new connections, processes any timed-out connection, and
+ * do other things required to run webserver.
+ * Once all connections are processed, function returns.
+ * This function is useful for quick and simple webserver implementation if
+ * application needs to run a single thread only and does not have any other
+ * network activity.
+ * @param daemon the daemon to run
+ * @param millisec the maximum time in milliseconds to wait for network and
+ * other events. Note: there is no guarantee that function
+ * blocks for specified amount of time. The real processing
+ * time can be shorter (if some data comes earlier) or
+ * longer (if data processing requires more time, especially
+ * in the user callbacks).
+ * If set to '0' then function does not block and processes
+ * only already available data (if any).
+ * If set to '-1' then function waits for events
+ * indefinitely (blocks until next network activity).
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or some serious
+ * unrecoverable error occurs.
+ * @note Available since #MHD_VERSION 0x00097206
+ * @ingroup event
+ */
+_MHD_EXTERN enum MHD_Result
+MHD_run_wait (struct MHD_Daemon *daemon,
+ int32_t millisec)
+{
+ enum MHD_Result res;
+ if ( (daemon->shutdown) ||
+ (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
+ return MHD_NO;
+
+ if (0 > millisec)
+ millisec = -1;
+ if (false)
+ {
+ (void) 0; /* Mute compiler warning */
+ }
+#ifdef HAVE_POLL
+ else if (0 != (daemon->options & MHD_USE_POLL))
{
- MHD_poll (daemon, MHD_NO);
+ res = MHD_poll_all (daemon, millisec);
MHD_cleanup_connections (daemon);
}
+#endif /* HAVE_POLL */
#ifdef EPOLL_SUPPORT
else if (0 != (daemon->options & MHD_USE_EPOLL))
{
- MHD_epoll (daemon, MHD_NO);
+ res = MHD_epoll (daemon, millisec);
MHD_cleanup_connections (daemon);
}
#endif
else
{
- MHD_select (daemon, MHD_NO);
+ res = MHD_select (daemon, millisec);
/* MHD_select does MHD_cleanup_connections already */
}
- return MHD_YES;
+ return res;
}
@@ -4517,71 +5183,106 @@
{
struct MHD_Daemon *daemon = pos->daemon;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+#endif /* MHD_USE_THREADS */
+
if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
- MHD_connection_mark_closed_ (pos);
- return; /* must let thread to do the rest */
- }
+ {
+ MHD_connection_mark_closed_ (pos);
+ return; /* must let thread to do the rest */
+ }
MHD_connection_close_ (pos,
MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
-
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
-
- EXTRA_CHECK (! pos->suspended);
- EXTRA_CHECK (! pos->resuming);
- if (pos->connection_timeout == pos->daemon->connection_timeout)
+#endif
+ mhd_assert (! pos->suspended);
+ mhd_assert (! pos->resuming);
+ if (pos->connection_timeout == daemon->connection_timeout)
XDLL_remove (daemon->normal_timeout_head,
- daemon->normal_timeout_tail,
- pos);
+ daemon->normal_timeout_tail,
+ pos);
else
XDLL_remove (daemon->manual_timeout_head,
- daemon->manual_timeout_tail,
- pos);
+ daemon->manual_timeout_tail,
+ pos);
DLL_remove (daemon->connections_head,
- daemon->connections_tail,
- pos);
+ daemon->connections_tail,
+ pos);
DLL_insert (daemon->cleanup_head,
- daemon->cleanup_tail,
- pos);
-
+ daemon->cleanup_tail,
+ pos);
+ daemon->data_already_pending = true;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
}
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
- * Thread that runs the select loop until the daemon
+ * Thread that runs the polling loop until the daemon
* is explicitly shut down.
*
* @param cls `struct MHD_Deamon` to run select loop in a thread for
* @return always 0 (on shutdown)
*/
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
-MHD_select_thread (void *cls)
+MHD_polling_thread (void *cls)
{
struct MHD_Daemon *daemon = cls;
+#ifdef HAVE_PTHREAD_SIGMASK
+ sigset_t s_mask;
+ int err;
+#endif /* HAVE_PTHREAD_SIGMASK */
+ MHD_thread_init_ (&(daemon->pid));
+#ifdef HAVE_PTHREAD_SIGMASK
+ if ((0 == sigemptyset (&s_mask)) &&
+ (0 == sigaddset (&s_mask, SIGPIPE)))
+ {
+ err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL);
+ }
+ else
+ err = errno;
+ if (0 == err)
+ daemon->sigpipe_blocked = true;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ ("Failed to block SIGPIPE on daemon thread: %s\n"),
+ MHD_strerror_ (errno));
+#endif /* HAVE_MESSAGES */
+#endif /* HAVE_PTHREAD_SIGMASK */
while (! daemon->shutdown)
- {
- if (0 != (daemon->options & MHD_USE_POLL))
- MHD_poll (daemon, MHD_YES);
+ {
+ if (0 != (daemon->options & MHD_USE_POLL))
+ MHD_poll (daemon, MHD_YES);
#ifdef EPOLL_SUPPORT
- else if (0 != (daemon->options & MHD_USE_EPOLL))
- MHD_epoll (daemon, MHD_YES);
+ else if (0 != (daemon->options & MHD_USE_EPOLL))
+ MHD_epoll (daemon, -1);
#endif
- else
- MHD_select (daemon, MHD_YES);
- MHD_cleanup_connections (daemon);
- }
+ else
+ MHD_select (daemon, -1);
+ MHD_cleanup_connections (daemon);
+ }
/* Resume any pending for resume connections, join
* all connection's threads (if any) and finally cleanup
* everything. */
+ if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
+ resume_suspended_connections (daemon);
close_all_connections (daemon);
- return (MHD_THRD_RTRN_TYPE_)0;
+ return (MHD_THRD_RTRN_TYPE_) 0;
}
+#endif
+
+
/**
* Process escape sequences ('%HH') Updates val in place; the
* result should be UTF-8 encoded and cannot be larger than the input.
@@ -4598,6 +5299,9 @@
struct MHD_Connection *connection,
char *val)
{
+ (void) cls; /* Mute compiler warning. */
+
+ (void) connection; /* Mute compiler warning. */
return MHD_http_unescape (val);
}
@@ -4607,7 +5311,11 @@
* #MHD_start_daemon_va.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if #MHD_OPTION_SOCK_ADDR or
+ * #MHD_OPTION_LISTEN_SOCKET is provided
+ * or #MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -4666,7 +5374,9 @@
MHD_socket
MHD_quiesce_daemon (struct MHD_Daemon *daemon)
{
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
unsigned int i;
+#endif
MHD_socket ret;
ret = daemon->listen_fd;
@@ -4674,55 +5384,62 @@
return MHD_INVALID_SOCKET;
if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
(0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
+ MHD_DLOG (daemon,
+ _ (
+ "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC.\n"));
#endif
- return MHD_INVALID_SOCKET;
- }
+ return MHD_INVALID_SOCKET;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if (NULL != daemon->worker_pool)
for (i = 0; i < daemon->worker_pool_size; i++)
- {
- daemon->worker_pool[i].was_quiesced = true;
+ {
+ daemon->worker_pool[i].was_quiesced = true;
#ifdef EPOLL_SUPPORT
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
- (-1 != daemon->worker_pool[i].epoll_fd) &&
- (daemon->worker_pool[i].listen_socket_in_epoll) )
- {
- if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
- EPOLL_CTL_DEL,
- ret,
- NULL))
- MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
- daemon->worker_pool[i].listen_socket_in_epoll = false;
- }
- else
+ if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ (-1 != daemon->worker_pool[i].epoll_fd) &&
+ (daemon->worker_pool[i].listen_socket_in_epoll) )
+ {
+ if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
+ EPOLL_CTL_DEL,
+ ret,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
+ daemon->worker_pool[i].listen_socket_in_epoll = false;
+ }
+ else
#endif
- if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
- {
- if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
- MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
- }
+ if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
+ {
+ if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
+ MHD_PANIC (_ (
+ "Failed to signal quiesce via inter-thread communication channel.\n"));
}
+ }
+#endif
daemon->was_quiesced = true;
#ifdef EPOLL_SUPPORT
if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
(-1 != daemon->epoll_fd) &&
(daemon->listen_socket_in_epoll) )
- {
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- ret,
- NULL))
- MHD_PANIC ("Failed to remove listen FD from epoll set\n");
- daemon->listen_socket_in_epoll = false;
- }
+ {
+ if ( (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ ret,
+ NULL)) &&
+ (ENOENT != errno) ) /* ENOENT can happen due to race with
+ #MHD_epoll() */
+ MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
+ daemon->listen_socket_in_epoll = false;
+ }
#endif
- if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
+ if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
(! MHD_itc_activate_ (daemon->itc, "q")) )
- MHD_PANIC (_("failed to signal quiesce via inter-thread communication channel"));
+ MHD_PANIC (_ (
+ "failed to signal quiesce via inter-thread communication channel.\n"));
return ret;
}
@@ -4748,10 +5465,10 @@
* @param ap the options
* @return #MHD_YES on success, #MHD_NO on error
*/
-static int
+static enum MHD_Result
parse_options_va (struct MHD_Daemon *daemon,
- const struct sockaddr **servaddr,
- va_list ap);
+ const struct sockaddr **servaddr,
+ va_list ap);
/**
@@ -4762,13 +5479,13 @@
* @param ... the options
* @return #MHD_YES on success, #MHD_NO on error
*/
-static int
+static enum MHD_Result
parse_options (struct MHD_Daemon *daemon,
- const struct sockaddr **servaddr,
- ...)
+ const struct sockaddr **servaddr,
+ ...)
{
va_list ap;
- int ret;
+ enum MHD_Result ret;
va_start (ap, servaddr);
ret = parse_options_va (daemon,
@@ -4787,455 +5504,624 @@
* @param ap the options
* @return #MHD_YES on success, #MHD_NO on error
*/
-static int
+static enum MHD_Result
parse_options_va (struct MHD_Daemon *daemon,
- const struct sockaddr **servaddr,
- va_list ap)
+ const struct sockaddr **servaddr,
+ va_list ap)
{
enum MHD_OPTION opt;
struct MHD_OptionItem *oa;
unsigned int i;
unsigned int uv;
#ifdef HTTPS_SUPPORT
- int ret;
+ enum MHD_Result ret;
const char *pstr;
+#if GNUTLS_VERSION_MAJOR >= 3
+ gnutls_certificate_retrieve_function2 *pgcrf;
+#endif
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ gnutls_certificate_retrieve_function3 *pgcrf2;
+#endif
#endif /* HTTPS_SUPPORT */
while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
- {
- switch (opt)
+ {
+ /* Increase counter at start, so resulting value is number of
+ * processed options, including any failed ones. */
+ daemon->num_opts++;
+ switch (opt)
+ {
+ case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
+ daemon->pool_size = va_arg (ap,
+ size_t);
+ break;
+ case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
+ daemon->pool_increment = va_arg (ap,
+ size_t);
+ break;
+ case MHD_OPTION_CONNECTION_LIMIT:
+ daemon->connection_limit = va_arg (ap,
+ unsigned int);
+ break;
+ case MHD_OPTION_CONNECTION_TIMEOUT:
+ uv = va_arg (ap,
+ unsigned int);
+ daemon->connection_timeout = (time_t) uv;
+ /* Next comparison could be always false on some platforms and whole branch will
+ * be optimized out on those platforms. On others it will be compiled into real
+ * check. */
+ if ( ( (MHD_TYPE_IS_SIGNED_ (time_t)) &&
+ (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */
+ (uv != (unsigned int) daemon->connection_timeout) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Warning: Too large timeout value, ignored.\n"));
+#endif
+ daemon->connection_timeout = 0;
+ }
+ break;
+ case MHD_OPTION_NOTIFY_COMPLETED:
+ daemon->notify_completed = va_arg (ap,
+ MHD_RequestCompletedCallback);
+ daemon->notify_completed_cls = va_arg (ap,
+ void *);
+ break;
+ case MHD_OPTION_NOTIFY_CONNECTION:
+ daemon->notify_connection = va_arg (ap,
+ MHD_NotifyConnectionCallback);
+ daemon->notify_connection_cls = va_arg (ap,
+ void *);
+ break;
+ case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
+ daemon->per_ip_connection_limit = va_arg (ap,
+ unsigned int);
+ break;
+ case MHD_OPTION_SOCK_ADDR:
+ *servaddr = va_arg (ap,
+ const struct sockaddr *);
+ break;
+ case MHD_OPTION_URI_LOG_CALLBACK:
+ daemon->uri_log_callback = va_arg (ap,
+ LogCallback);
+ daemon->uri_log_callback_cls = va_arg (ap,
+ void *);
+ break;
+ case MHD_OPTION_SERVER_INSANITY:
+ daemon->insanity_level = (enum MHD_DisableSanityCheck)
+ va_arg (ap,
+ unsigned int);
+ break;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ case MHD_OPTION_THREAD_POOL_SIZE:
+ daemon->worker_pool_size = va_arg (ap,
+ unsigned int);
+ if (0 == daemon->worker_pool_size)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Warning: Zero size, specified for thread pool size, is ignored. "
+ "Thread pool is not used.\n"));
+#endif
+ }
+ else if (1 == daemon->worker_pool_size)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Warning: \"1\", specified for thread pool size, is ignored. "
+ "Thread pool is not used.\n"));
+#endif
+ daemon->worker_pool_size = 0;
+ }
+#if (0 == (UINT_MAX + 0)) || (UINT_MAX >= (SIZE_MAX / (64 * 1024)))
+ /* Next comparison could be always false on some platforms and whole branch will
+ * be optimized out on these platforms. On others it will be compiled into real
+ * check. */
+ else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct
+ MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Specified thread pool size (%u) too big.\n"),
+ daemon->worker_pool_size);
+#endif
+ return MHD_NO;
+ }
+#endif /* (UINT_MAX >= (SIZE_MAX/(64*1024))) */
+ else
+ {
+ if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
{
- case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
- daemon->pool_size = va_arg (ap,
- size_t);
- break;
- case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
- daemon->pool_increment= va_arg (ap,
- size_t);
- break;
- case MHD_OPTION_CONNECTION_LIMIT:
- daemon->connection_limit = va_arg (ap,
- unsigned int);
- break;
- case MHD_OPTION_CONNECTION_TIMEOUT:
- uv = va_arg (ap,
- unsigned int);
- if (TIME_T_MAX < uv)
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Warning: Too large timeout value, ignored.\n"));
+ MHD_DLOG (daemon,
+ _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
+ "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
#endif
- daemon->connection_timeout = 0;
- }
- else
- daemon->connection_timeout = (time_t)uv;
- break;
- case MHD_OPTION_NOTIFY_COMPLETED:
- daemon->notify_completed = va_arg (ap,
- MHD_RequestCompletedCallback);
- daemon->notify_completed_cls = va_arg (ap,
- void *);
- break;
- case MHD_OPTION_NOTIFY_CONNECTION:
- daemon->notify_connection = va_arg (ap,
- MHD_NotifyConnectionCallback);
- daemon->notify_connection_cls = va_arg (ap,
- void *);
- break;
- case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
- daemon->per_ip_connection_limit = va_arg (ap,
- unsigned int);
- break;
- case MHD_OPTION_SOCK_ADDR:
- *servaddr = va_arg (ap,
- const struct sockaddr *);
- break;
- case MHD_OPTION_URI_LOG_CALLBACK:
- daemon->uri_log_callback = va_arg (ap,
- LogCallback);
- daemon->uri_log_callback_cls = va_arg (ap,
- void *);
- break;
- case MHD_OPTION_THREAD_POOL_SIZE:
- daemon->worker_pool_size = va_arg (ap,
- unsigned int);
- if (0 == daemon->worker_pool_size)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Warning: Zero size, specified for thread pool size, is ignored. "
- "Thread pool is not used.\n"));
-#endif
- }
- else if (1 == daemon->worker_pool_size)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Warning: \"1\", specified for thread pool size, is ignored. "
- "Thread pool is not used.\n"));
-#endif
- daemon->worker_pool_size = 0;
- }
- else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Specified thread pool size (%u) too big\n"),
- daemon->worker_pool_size);
-#endif
- return MHD_NO;
- }
- else
- {
- if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
- "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
-#endif
- return MHD_NO;
- }
- if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Both MHD_OPTION_THREAD_POOL_SIZE option and "
- "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
-#endif
- return MHD_NO;
- }
- }
- break;
-#ifdef HTTPS_SUPPORT
- case MHD_OPTION_HTTPS_MEM_KEY:
- if (0 != (daemon->options & MHD_USE_TLS))
- daemon->https_mem_key = va_arg (ap,
- const char *);
-#ifdef HAVE_MESSAGES
- else
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
- opt);
+ return MHD_NO;
+ }
+ if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and "
+ "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
#endif
- break;
- case MHD_OPTION_HTTPS_KEY_PASSWORD:
- if (0 != (daemon->options & MHD_USE_TLS))
- daemon->https_key_password = va_arg (ap,
- const char *);
-#ifdef HAVE_MESSAGES
- else
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
- opt);
+ return MHD_NO;
+ }
+ }
+ break;
#endif
- break;
- case MHD_OPTION_HTTPS_MEM_CERT:
- if (0 != (daemon->options & MHD_USE_TLS))
- daemon->https_mem_cert = va_arg (ap,
- const char *);
-#ifdef HAVE_MESSAGES
- else
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
- opt);
+#ifdef HTTPS_SUPPORT
+ case MHD_OPTION_HTTPS_MEM_KEY:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->https_mem_key = pstr;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_KEY_PASSWORD:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->https_key_password = pstr;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_MEM_CERT:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->https_mem_cert = pstr;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_MEM_TRUST:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->https_mem_trust = pstr;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_CRED_TYPE:
+ daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
+ int);
+ break;
+ case MHD_OPTION_HTTPS_MEM_DHPARAMS:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ {
+ gnutls_datum_t dhpar;
+ size_t pstr_len;
+
+ if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Error initializing DH parameters.\n"));
#endif
- break;
- case MHD_OPTION_HTTPS_MEM_TRUST:
- if (0 != (daemon->options & MHD_USE_TLS))
- daemon->https_mem_trust = va_arg (ap,
- const char *);
-#ifdef HAVE_MESSAGES
- else
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
- opt);
+ return MHD_NO;
+ }
+ dhpar.data = (unsigned char *) pstr;
+ pstr_len = strlen (pstr);
+ if (UINT_MAX < pstr_len)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Diffie-Hellman parameters string too long.\n"));
#endif
- break;
- case MHD_OPTION_HTTPS_CRED_TYPE:
- daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
- int);
- break;
- case MHD_OPTION_HTTPS_MEM_DHPARAMS:
- if (0 != (daemon->options & MHD_USE_TLS))
- {
- const char *arg = va_arg (ap,
- const char *);
- gnutls_datum_t dhpar;
-
- if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Error initializing DH parameters\n"));
-#endif
- return MHD_NO;
- }
- dhpar.data = (unsigned char *) arg;
- dhpar.size = strlen (arg);
- if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
- &dhpar,
- GNUTLS_X509_FMT_PEM) < 0)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Bad Diffie-Hellman parameters format\n"));
-#endif
- gnutls_dh_params_deinit (daemon->https_mem_dhparams);
- return MHD_NO;
- }
- daemon->have_dhparams = true;
- }
- else
- {
+ return MHD_NO;
+ }
+ dhpar.size = (unsigned int) pstr_len;
+ if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
+ &dhpar,
+ GNUTLS_X509_FMT_PEM) < 0)
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
- opt);
+ MHD_DLOG (daemon,
+ _ ("Bad Diffie-Hellman parameters format.\n"));
#endif
- return MHD_NO;
- }
- break;
- case MHD_OPTION_HTTPS_PRIORITIES:
- if (0 != (daemon->options & MHD_USE_TLS))
- {
- gnutls_priority_deinit (daemon->priority_cache);
- ret = gnutls_priority_init (&daemon->priority_cache,
- pstr = va_arg (ap, const char*),
- NULL);
- if (GNUTLS_E_SUCCESS != ret)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Setting priorities to `%s' failed: %s\n"),
- pstr,
- gnutls_strerror (ret));
-#endif
- daemon->priority_cache = NULL;
- return MHD_NO;
- }
- }
- break;
- case MHD_OPTION_HTTPS_CERT_CALLBACK:
-#if GNUTLS_VERSION_MAJOR < 3
+ gnutls_dh_params_deinit (daemon->https_mem_dhparams);
+ return MHD_NO;
+ }
+ daemon->have_dhparams = true;
+ }
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_PRIORITIES:
+ pstr = va_arg (ap,
+ const char *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ {
+ gnutls_priority_deinit (daemon->priority_cache);
+ ret = gnutls_priority_init (&daemon->priority_cache,
+ pstr,
+ NULL);
+ if (GNUTLS_E_SUCCESS != ret)
+ {
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
+ _ ("Setting priorities to `%s' failed: %s\n"),
+ pstr,
+ gnutls_strerror (ret));
#endif
+ daemon->priority_cache = NULL;
return MHD_NO;
+ }
+ }
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif
+ break;
+ case MHD_OPTION_HTTPS_CERT_CALLBACK:
+#if GNUTLS_VERSION_MAJOR < 3
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0.\n"));
+#endif
+ return MHD_NO;
#else
- if (0 != (daemon->options & MHD_USE_TLS))
- daemon->cert_callback = va_arg (ap,
- gnutls_certificate_retrieve_function2 *);
- break;
+ pgcrf = va_arg (ap,
+ gnutls_certificate_retrieve_function2 *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->cert_callback = pgcrf;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif /* HAVE_MESSAGES */
+ break;
+#endif
+ case MHD_OPTION_HTTPS_CERT_CALLBACK2:
+#if GNUTLS_VERSION_NUMBER < 0x030603
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3.\n"));
+#endif
+ return MHD_NO;
+#else
+ pgcrf2 = va_arg (ap,
+ gnutls_certificate_retrieve_function3 *);
+ if (0 != (daemon->options & MHD_USE_TLS))
+ daemon->cert_callback2 = pgcrf2;
+#ifdef HAVE_MESSAGES
+ else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
+ opt);
+#endif /* HAVE_MESSAGES */
+ break;
#endif
#endif /* HTTPS_SUPPORT */
#ifdef DAUTH_SUPPORT
- case MHD_OPTION_DIGEST_AUTH_RANDOM:
- daemon->digest_auth_rand_size = va_arg (ap,
- size_t);
- daemon->digest_auth_random = va_arg (ap,
- const char *);
- break;
- case MHD_OPTION_NONCE_NC_SIZE:
- daemon->nonce_nc_size = va_arg (ap,
- unsigned int);
- break;
-#endif
- case MHD_OPTION_LISTEN_SOCKET:
- if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD_OPTION_LISTEN_SOCKET specified for daemon "
- "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
+ case MHD_OPTION_DIGEST_AUTH_RANDOM:
+ daemon->digest_auth_rand_size = va_arg (ap,
+ size_t);
+ daemon->digest_auth_random = va_arg (ap,
+ const char *);
+ break;
+ case MHD_OPTION_NONCE_NC_SIZE:
+ daemon->nonce_nc_size = va_arg (ap,
+ unsigned int);
+ break;
+#endif
+ case MHD_OPTION_LISTEN_SOCKET:
+ if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon "
+ "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
+ else
+ {
+ daemon->listen_fd = va_arg (ap,
+ MHD_socket);
+#if defined(SO_DOMAIN) && defined(AF_UNIX)
+ {
+ int af;
+ socklen_t len = sizeof (af);
+
+ if (0 == getsockopt (daemon->listen_fd,
+ SOL_SOCKET,
+ SO_DOMAIN,
+ &af,
+ &len))
+ {
+ daemon->listen_is_unix = (AF_UNIX == af) ? _MHD_YES : _MHD_NO;
+ }
else
- daemon->listen_fd = va_arg (ap,
- MHD_socket);
- break;
- case MHD_OPTION_EXTERNAL_LOGGER:
+ daemon->listen_is_unix = _MHD_UNKNOWN;
+ }
+#else /* ! SO_DOMAIN || ! AF_UNIX */
+ daemon->listen_is_unix = _MHD_UNKNOWN;
+#endif /* ! SO_DOMAIN || ! AF_UNIX */
+ }
+ break;
+ case MHD_OPTION_EXTERNAL_LOGGER:
#ifdef HAVE_MESSAGES
- daemon->custom_error_log = va_arg (ap,
- VfprintfFunctionPointerType);
- daemon->custom_error_log_cls = va_arg (ap,
- void *);
+ daemon->custom_error_log = va_arg (ap,
+ VfprintfFunctionPointerType);
+ daemon->custom_error_log_cls = va_arg (ap,
+ void *);
+ if (1 != daemon->num_opts)
+ MHD_DLOG (daemon,
+ _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option "
+ "specified for the daemon. Some messages may be "
+ "printed by the standard MHD logger.\n"));
+
#else
- va_arg (ap,
- VfprintfFunctionPointerType);
- va_arg (ap,
- void *);
+ va_arg (ap,
+ VfprintfFunctionPointerType);
+ va_arg (ap,
+ void *);
+#endif
+ break;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ case MHD_OPTION_THREAD_STACK_SIZE:
+ daemon->thread_stack_size = va_arg (ap,
+ size_t);
+ break;
#endif
- break;
+ case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
+#ifdef TCP_FASTOPEN
+ daemon->fastopen_queue_size = va_arg (ap,
+ unsigned int);
+ break;
+#else /* ! TCP_FASTOPEN */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("TCP fastopen is not supported on this platform.\n"));
+#endif /* HAVE_MESSAGES */
+ return MHD_NO;
+#endif /* ! TCP_FASTOPEN */
+ case MHD_OPTION_LISTENING_ADDRESS_REUSE:
+ daemon->listening_address_reuse = va_arg (ap,
+ unsigned int) ? 1 : -1;
+ break;
+ case MHD_OPTION_LISTEN_BACKLOG_SIZE:
+ daemon->listen_backlog_size = va_arg (ap,
+ unsigned int);
+ break;
+ case MHD_OPTION_STRICT_FOR_CLIENT:
+ daemon->strict_for_client = va_arg (ap, int);
+#ifdef HAVE_MESSAGES
+ if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
+ (1 != daemon->strict_for_client) )
+ {
+ MHD_DLOG (daemon,
+ _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
+ "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
+ }
+#endif /* HAVE_MESSAGES */
+ break;
+ case MHD_OPTION_ARRAY:
+ daemon->num_opts--; /* Do not count MHD_OPTION_ARRAY */
+ oa = va_arg (ap, struct MHD_OptionItem*);
+ i = 0;
+ while (MHD_OPTION_END != (opt = oa[i].option))
+ {
+ switch (opt)
+ {
+ /* all options taking 'size_t' */
+ case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
+ case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
case MHD_OPTION_THREAD_STACK_SIZE:
- daemon->thread_stack_size = va_arg (ap,
- size_t);
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (size_t) oa[i].value,
+ MHD_OPTION_END))
+ return MHD_NO;
break;
-#ifdef TCP_FASTOPEN
+ /* all options taking 'unsigned int' */
+ case MHD_OPTION_NONCE_NC_SIZE:
+ case MHD_OPTION_CONNECTION_LIMIT:
+ case MHD_OPTION_CONNECTION_TIMEOUT:
+ case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
+ case MHD_OPTION_THREAD_POOL_SIZE:
case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
- daemon->fastopen_queue_size = va_arg (ap,
- unsigned int);
+ case MHD_OPTION_LISTENING_ADDRESS_REUSE:
+ case MHD_OPTION_LISTEN_BACKLOG_SIZE:
+ case MHD_OPTION_SERVER_INSANITY:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (unsigned int) oa[i].value,
+ MHD_OPTION_END))
+ return MHD_NO;
break;
-#endif
- case MHD_OPTION_LISTENING_ADDRESS_REUSE:
- daemon->listening_address_reuse = va_arg (ap,
- unsigned int) ? 1 : -1;
- break;
- case MHD_OPTION_LISTEN_BACKLOG_SIZE:
- daemon->listen_backlog_size = va_arg (ap,
- unsigned int);
- break;
- case MHD_OPTION_STRICT_FOR_CLIENT:
- daemon->strict_for_client = va_arg (ap, int);;
-#ifdef HAVE_MESSAGES
- if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
- (1 != daemon->strict_for_client) )
- {
- MHD_DLOG (daemon,
- _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
- "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
- }
-#endif /* HAVE_MESSAGES */
- break;
- case MHD_OPTION_ARRAY:
- oa = va_arg (ap, struct MHD_OptionItem*);
- i = 0;
- while (MHD_OPTION_END != (opt = oa[i].option))
- {
- switch (opt)
- {
- /* all options taking 'size_t' */
- case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
- case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
- case MHD_OPTION_THREAD_STACK_SIZE:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (size_t) oa[i].value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* all options taking 'unsigned int' */
- case MHD_OPTION_NONCE_NC_SIZE:
- case MHD_OPTION_CONNECTION_LIMIT:
- case MHD_OPTION_CONNECTION_TIMEOUT:
- case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
- case MHD_OPTION_THREAD_POOL_SIZE:
- case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
- case MHD_OPTION_LISTENING_ADDRESS_REUSE:
- case MHD_OPTION_LISTEN_BACKLOG_SIZE:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (unsigned int) oa[i].value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* all options taking 'enum' */
+ /* all options taking 'enum' */
#ifdef HTTPS_SUPPORT
- case MHD_OPTION_HTTPS_CRED_TYPE:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (gnutls_credentials_type_t) oa[i].value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
+ case MHD_OPTION_HTTPS_CRED_TYPE:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (gnutls_credentials_type_t) oa[i].value,
+ MHD_OPTION_END))
+ return MHD_NO;
+ break;
#endif /* HTTPS_SUPPORT */
- /* all options taking 'MHD_socket' */
- case MHD_OPTION_LISTEN_SOCKET:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (MHD_socket) oa[i].value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* all options taking 'int' */
- case MHD_OPTION_STRICT_FOR_CLIENT:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (int) oa[i].value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* all options taking one pointer */
- case MHD_OPTION_SOCK_ADDR:
- case MHD_OPTION_HTTPS_MEM_KEY:
- case MHD_OPTION_HTTPS_KEY_PASSWORD:
- case MHD_OPTION_HTTPS_MEM_CERT:
- case MHD_OPTION_HTTPS_MEM_TRUST:
- case MHD_OPTION_HTTPS_MEM_DHPARAMS:
- case MHD_OPTION_HTTPS_PRIORITIES:
- case MHD_OPTION_ARRAY:
- case MHD_OPTION_HTTPS_CERT_CALLBACK:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- oa[i].ptr_value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* all options taking two pointers */
- case MHD_OPTION_NOTIFY_COMPLETED:
- case MHD_OPTION_NOTIFY_CONNECTION:
- case MHD_OPTION_URI_LOG_CALLBACK:
- case MHD_OPTION_EXTERNAL_LOGGER:
- case MHD_OPTION_UNESCAPE_CALLBACK:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (void *) oa[i].value,
- oa[i].ptr_value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- /* options taking size_t-number followed by pointer */
- case MHD_OPTION_DIGEST_AUTH_RANDOM:
- if (MHD_YES != parse_options (daemon,
- servaddr,
- opt,
- (size_t) oa[i].value,
- oa[i].ptr_value,
- MHD_OPTION_END))
- return MHD_NO;
- break;
- default:
- return MHD_NO;
- }
- i++;
- }
- break;
+ /* all options taking 'MHD_socket' */
+ case MHD_OPTION_LISTEN_SOCKET:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (MHD_socket) oa[i].value,
+ MHD_OPTION_END))
+ return MHD_NO;
+ break;
+ /* all options taking 'int' */
+ case MHD_OPTION_STRICT_FOR_CLIENT:
+ case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
+ case MHD_OPTION_TLS_NO_ALPN:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (int) oa[i].value,
+ MHD_OPTION_END))
+ return MHD_NO;
+ break;
+ /* all options taking one pointer */
+ case MHD_OPTION_SOCK_ADDR:
+ case MHD_OPTION_HTTPS_MEM_KEY:
+ case MHD_OPTION_HTTPS_KEY_PASSWORD:
+ case MHD_OPTION_HTTPS_MEM_CERT:
+ case MHD_OPTION_HTTPS_MEM_TRUST:
+ case MHD_OPTION_HTTPS_MEM_DHPARAMS:
+ case MHD_OPTION_HTTPS_PRIORITIES:
+ case MHD_OPTION_ARRAY:
+ case MHD_OPTION_HTTPS_CERT_CALLBACK:
+ case MHD_OPTION_HTTPS_CERT_CALLBACK2:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ oa[i].ptr_value,
+ MHD_OPTION_END))
+ return MHD_NO;
+ break;
+ /* all options taking two pointers */
+ case MHD_OPTION_NOTIFY_COMPLETED:
+ case MHD_OPTION_NOTIFY_CONNECTION:
+ case MHD_OPTION_URI_LOG_CALLBACK:
+ case MHD_OPTION_EXTERNAL_LOGGER:
case MHD_OPTION_UNESCAPE_CALLBACK:
- daemon->unescape_callback = va_arg (ap,
- UnescapeCallback);
- daemon->unescape_callback_cls = va_arg (ap,
- void *);
+ case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (void *) oa[i].value,
+ oa[i].ptr_value,
+ MHD_OPTION_END))
+ return MHD_NO;
+ break;
+ /* options taking size_t-number followed by pointer */
+ case MHD_OPTION_DIGEST_AUTH_RANDOM:
+ if (MHD_NO == parse_options (daemon,
+ servaddr,
+ opt,
+ (size_t) oa[i].value,
+ oa[i].ptr_value,
+ MHD_OPTION_END))
+ return MHD_NO;
break;
default:
+ return MHD_NO;
+ }
+ i++;
+ }
+ break;
+ case MHD_OPTION_UNESCAPE_CALLBACK:
+ daemon->unescape_callback = va_arg (ap,
+ UnescapeCallback);
+ daemon->unescape_callback_cls = va_arg (ap,
+ void *);
+ break;
+#ifdef HTTPS_SUPPORT
+ case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
+#if GNUTLS_VERSION_MAJOR >= 3
+ daemon->cred_callback = va_arg (ap,
+ MHD_PskServerCredentialsCallback);
+ daemon->cred_callback_cls = va_arg (ap,
+ void *);
+ break;
+#else
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3.\n"),
+ opt);
+ return MHD_NO;
+#endif
+#endif /* HTTPS_SUPPORT */
+ case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
+ if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ daemon->sigpipe_blocked = ( (va_arg (ap,
+ int)) != 0);
+ else
+ {
+ (void) va_arg (ap,
+ int);
+ }
+ break;
+ case MHD_OPTION_TLS_NO_ALPN:
+#ifdef HTTPS_SUPPORT
+ daemon->disable_alpn = (va_arg (ap,
+ int) != 0);
+#else /* ! HTTPS_SUPPORT */
+ (void) va_arg (ap, int);
+#endif /* ! HTTPS_SUPPORT */
#ifdef HAVE_MESSAGES
- if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
- (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
- (opt == MHD_OPTION_HTTPS_MEM_TRUST))
- {
- MHD_DLOG (daemon,
- _("MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
- opt);
- }
- else
- {
- MHD_DLOG (daemon,
- _("Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
- opt);
- }
+ if (0 == (daemon->options & MHD_USE_TLS))
+ MHD_DLOG (daemon,
+ _ ("MHD HTTPS option %d passed to MHD " \
+ "but MHD_USE_TLS not set.\n"),
+ (int) opt);
+#endif /* HAVE_MESSAGES */
+ break;
+ default:
+#ifdef HAVE_MESSAGES
+ if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
+ (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
+ (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
+ (opt == MHD_OPTION_GNUTLS_PSK_CRED_HANDLER) )
+ {
+ MHD_DLOG (daemon,
+ _ (
+ "MHD HTTPS option %d passed to MHD compiled without HTTPS support.\n"),
+ opt);
+ }
+ else
+ {
+ MHD_DLOG (daemon,
+ _ (
+ "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?).\n"),
+ opt);
+ }
#endif
- return MHD_NO;
- }
+ return MHD_NO;
}
+ }
return MHD_YES;
}
@@ -5246,28 +6132,32 @@
{
int fd;
+#ifndef HAVE_MESSAGES
+ (void) daemon; /* Mute compiler warning. */
+#endif /* ! HAVE_MESSAGES */
+
#ifdef USE_EPOLL_CREATE1
fd = epoll_create1 (EPOLL_CLOEXEC);
#else /* ! USE_EPOLL_CREATE1 */
fd = epoll_create (MAX_EVENTS);
#endif /* ! USE_EPOLL_CREATE1 */
if (MHD_INVALID_SOCKET == fd)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_create1 failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_create1 failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- return MHD_INVALID_SOCKET;
- }
-#if !defined(USE_EPOLL_CREATE1)
+ return MHD_INVALID_SOCKET;
+ }
+#if ! defined(USE_EPOLL_CREATE1)
if (! MHD_socket_noninheritable_ (fd))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set noninheritable mode on epoll FD.\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to set noninheritable mode on epoll FD.\n"));
#endif
- }
+ }
#endif /* ! USE_EPOLL_CREATE1 */
return fd;
}
@@ -5276,66 +6166,74 @@
/**
* Setup epoll() FD for the daemon and initialize it to listen
* on the listen FD.
- * @remark To be called only from thread that process
- * daemon's select()/poll()/etc.
+ * @remark To be called only from MHD_start_daemon_va()
*
* @param daemon daemon to initialize for epoll()
* @return #MHD_YES on success, #MHD_NO on failure
*/
-static int
+static enum MHD_Result
setup_epoll_to_listen (struct MHD_Daemon *daemon)
{
struct epoll_event event;
MHD_socket ls;
+ mhd_assert (0 != (daemon->options & MHD_USE_EPOLL));
+ mhd_assert (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \
+ MHD_ITC_IS_VALID_ (daemon->itc) );
daemon->epoll_fd = setup_epoll_fd (daemon);
if (-1 == daemon->epoll_fd)
return MHD_NO;
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
- {
- daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
- if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
- return MHD_NO;
- }
+ {
+ daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
+ if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
+ return MHD_NO;
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
- if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
- (daemon->was_quiesced) )
- return MHD_YES; /* non-listening daemon */
- event.events = EPOLLIN;
- event.data.ptr = daemon;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- ls,
- &event))
+ if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+ (! daemon->was_quiesced) )
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = daemon;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ ls,
+ &event))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
+ _ ("Call to epoll_ctl failed: %s\n"),
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
- daemon->listen_socket_in_epoll = true;
- if (MHD_ITC_IS_VALID_(daemon->itc))
+ daemon->listen_socket_in_epoll = true;
+ }
+
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ event.events = EPOLLIN;
+ event.data.ptr = (void *) epoll_itc_marker;
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_ADD,
+ MHD_itc_r_fd_ (daemon->itc),
+ &event))
{
- event.events = EPOLLIN;
- event.data.ptr = (void *) epoll_itc_marker;
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_ADD,
- MHD_itc_r_fd_ (daemon->itc),
- &event))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- return MHD_NO;
- }
+ return MHD_NO;
}
+ }
return MHD_YES;
}
+
+
#endif
@@ -5343,7 +6241,11 @@
* Start a webserver on the given port.
*
* @param flags combination of `enum MHD_FLAG` values
- * @param port port to bind to (in host byte order)
+ * @param port port to bind to (in host byte order),
+ * use '0' to bind to random free port,
+ * ignored if #MHD_OPTION_SOCK_ADDR or
+ * #MHD_OPTION_LISTEN_SOCKET is provided
+ * or #MHD_USE_NO_LISTEN_SOCKET is specified
* @param apc callback to call to check which clients
* will be allowed to connect; you can pass NULL
* in which case connections from any IP will be
@@ -5363,7 +6265,7 @@
void *apc_cls,
MHD_AccessHandlerCallback dh,
void *dh_cls,
- va_list ap)
+ va_list ap)
{
const MHD_SCKT_OPT_BOOL_ on = 1;
struct MHD_Daemon *daemon;
@@ -5374,10 +6276,13 @@
#endif
const struct sockaddr *servaddr = NULL;
socklen_t addrlen;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
unsigned int i;
+#endif
enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
enum MHD_FLAG *pflags;
+ MHD_check_global_init_ ();
eflags = (enum MHD_FLAG) flags;
pflags = &eflags;
#ifndef HAVE_INET6
@@ -5401,56 +6306,61 @@
return NULL;
#endif
if (0 != (*pflags & MHD_ALLOW_UPGRADE))
- {
+ {
#ifdef UPGRADE_SUPPORT
- *pflags |= MHD_ALLOW_SUSPEND_RESUME;
+ *pflags |= MHD_ALLOW_SUSPEND_RESUME;
#else /* ! UPGRADE_SUPPORT */
- return NULL;
+ return NULL;
#endif /* ! UPGRADE_SUPPORT */
- }
+ }
if (NULL == dh)
return NULL;
/* Check for invalid combinations of flags. */
if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
- ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) ||
+ ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags
+ &
+ MHD_USE_THREAD_PER_CONNECTION)))
+ ||
((0 != (*pflags & MHD_USE_POLL)) &&
- (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION)))) ||
- ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
+ (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION)))) ||
+ ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL
+ | MHD_USE_EPOLL)))) )
return NULL;
if (0 != (*pflags & MHD_USE_AUTO))
+ {
+ if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
{
- if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
- {
- /* Thread per connection with internal polling thread. */
+ /* Thread per connection with internal polling thread. */
#ifdef HAVE_POLL
- *pflags |= MHD_USE_POLL;
+ *pflags |= MHD_USE_POLL;
#else /* ! HAVE_POLL */
- /* use select() - do not modify flags */
+ /* use select() - do not modify flags */
#endif /* ! HAVE_POLL */
- }
- else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
- {
- /* Internal polling thread. */
+ }
+ else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
+ {
+ /* Internal polling thread. */
#if defined(EPOLL_SUPPORT)
- *pflags |= MHD_USE_EPOLL;
+ *pflags |= MHD_USE_EPOLL;
#elif defined(HAVE_POLL)
- *pflags |= MHD_USE_POLL;
+ *pflags |= MHD_USE_POLL;
#else /* !HAVE_POLL && !EPOLL_SUPPORT */
- /* use select() - do not modify flags */
+ /* use select() - do not modify flags */
#endif /* !HAVE_POLL && !EPOLL_SUPPORT */
- }
- else
- {
- /* Internal threads are not used - "external" polling mode. */
+ }
+ else
+ {
+ /* Internal threads are not used - "external" polling mode. */
#if defined(EPOLL_SUPPORT)
- *pflags |= MHD_USE_EPOLL;
+ *pflags |= MHD_USE_EPOLL;
#else /* ! EPOLL_SUPPORT */
- /* use select() - do not modify flags */
+ /* use select() - do not modify flags */
#endif /* ! EPOLL_SUPPORT */
- }
}
+ }
if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
return NULL;
@@ -5464,17 +6374,19 @@
#ifdef HTTPS_SUPPORT
daemon->priority_cache = NULL;
if (0 != (*pflags & MHD_USE_TLS))
- {
- gnutls_priority_init (&daemon->priority_cache,
- "NORMAL",
- NULL);
- }
+ {
+ gnutls_priority_init (&daemon->priority_cache,
+ "NORMAL",
+ NULL);
+ }
#endif /* HTTPS_SUPPORT */
daemon->listen_fd = MHD_INVALID_SOCKET;
+ daemon->listen_is_unix = _MHD_NO;
daemon->listening_address_reuse = 0;
daemon->options = *pflags;
pflags = &daemon->options;
- daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : 0;
+ daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 :
+ 0;
daemon->port = port;
daemon->apc = apc;
daemon->apc_cls = apc_cls;
@@ -5493,29 +6405,31 @@
daemon->listen_backlog_size = 511; /* should be safe value */
#endif /* !SOMAXCONN */
#ifdef HAVE_MESSAGES
- daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
+ daemon->custom_error_log = &MHD_default_logger_;
daemon->custom_error_log_cls = stderr;
#endif
+#ifndef MHD_WINSOCK_SOCKETS
+ daemon->sigpipe_blocked = false;
+#else /* MHD_WINSOCK_SOCKETS */
+ /* There is no SIGPIPE on W32, nothing to block. */
+ daemon->sigpipe_blocked = true;
+#endif /* _WIN32 && ! __CYGWIN__ */
+
if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
(0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
- "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
- "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
-#endif
- *pflags |= MHD_USE_INTERNAL_POLLING_THREAD;
- }
+ {
+ /* Log warning message later, when log parameters are processes */
+ *pflags |= MHD_USE_INTERNAL_POLLING_THREAD;
+ }
if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
*pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
else
- {
+ {
#ifdef HAVE_LISTEN_SHUTDOWN
- if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
+ if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
#endif
- *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
- }
+ *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
+ }
#ifdef DAUTH_SUPPORT
daemon->digest_auth_rand_size = 0;
daemon->digest_auth_random = NULL;
@@ -5523,474 +6437,636 @@
#endif
#ifdef HTTPS_SUPPORT
if (0 != (*pflags & MHD_USE_TLS))
- {
- daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
- }
+ {
+ daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
+ }
#endif /* HTTPS_SUPPORT */
- if (MHD_YES != parse_options_va (daemon,
- &servaddr,
- ap))
- {
+ if (MHD_NO == parse_options_va (daemon,
+ &servaddr,
+ ap))
+ {
#ifdef HTTPS_SUPPORT
- if ( (0 != (*pflags & MHD_USE_TLS)) &&
- (NULL != daemon->priority_cache) )
- gnutls_priority_deinit (daemon->priority_cache);
+ if ( (0 != (*pflags & MHD_USE_TLS)) &&
+ (NULL != daemon->priority_cache) )
+ gnutls_priority_deinit (daemon->priority_cache);
#endif /* HTTPS_SUPPORT */
- free (daemon);
- return NULL;
- }
- if ( (0 != (*pflags & MHD_USE_ITC)) &&
- (0 == daemon->worker_pool_size) )
+ free (daemon);
+ return NULL;
+ }
+
+#ifdef HAVE_MESSAGES
+ if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) )
+ {
+ MHD_DLOG (daemon,
+ _ (
+ "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
+ "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
+ "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
+ }
+#endif
+
+ if ( (NULL != daemon->notify_completed) &&
+ (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
+ *pflags |= MHD_USE_ITC; /* requires ITC */
+
+#ifndef NDEBUG
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Using debug build of libmicrohttpd.\n") );
+#endif /* HAVE_MESSAGES */
+#endif /* ! NDEBUG */
+
+ if ( (0 != (*pflags & MHD_USE_ITC))
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ && (0 == daemon->worker_pool_size)
+#endif
+ )
+ {
+ if (! MHD_itc_init_ (daemon->itc))
{
- if (! MHD_itc_init_ (daemon->itc))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to create inter-thread communication channel: %s\n"),
- MHD_itc_last_strerror_ ());
+ MHD_DLOG (daemon,
+ _ ("Failed to create inter-thread communication channel: %s\n"),
+ MHD_itc_last_strerror_ ());
#endif
#ifdef HTTPS_SUPPORT
- if (NULL != daemon->priority_cache)
- gnutls_priority_deinit (daemon->priority_cache);
+ if (NULL != daemon->priority_cache)
+ gnutls_priority_deinit (daemon->priority_cache);
#endif /* HTTPS_SUPPORT */
- free (daemon);
- return NULL;
- }
- if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
- (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc),
- NULL)) )
- {
+ free (daemon);
+ return NULL;
+ }
+ if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc),
+ NULL)) )
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("file descriptor for inter-thread communication channel exceeds maximum value\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "file descriptor for inter-thread communication channel exceeds maximum value.\n"));
#endif
- MHD_itc_destroy_chk_ (daemon->itc);
+ MHD_itc_destroy_chk_ (daemon->itc);
#ifdef HTTPS_SUPPORT
- if (NULL != daemon->priority_cache)
- gnutls_priority_deinit (daemon->priority_cache);
+ if (NULL != daemon->priority_cache)
+ gnutls_priority_deinit (daemon->priority_cache);
#endif /* HTTPS_SUPPORT */
- free (daemon);
- return NULL;
- }
+ free (daemon);
+ return NULL;
}
+ }
#ifdef DAUTH_SUPPORT
if (daemon->nonce_nc_size > 0)
+ {
+ if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)))
+ / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
{
- if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
- sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Specified value for NC_SIZE too large\n"));
-#endif
-#ifdef HTTPS_SUPPORT
- if (0 != (*pflags & MHD_USE_TLS))
- gnutls_priority_deinit (daemon->priority_cache);
-#endif /* HTTPS_SUPPORT */
- free (daemon);
- return NULL;
- }
- daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
- if (NULL == daemon->nnc)
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to allocate memory for nonce-nc map: %s\n"),
- MHD_strerror_ (errno));
+ MHD_DLOG (daemon,
+ _ ("Specified value for NC_SIZE too large.\n"));
#endif
#ifdef HTTPS_SUPPORT
- if (0 != (*pflags & MHD_USE_TLS))
- gnutls_priority_deinit (daemon->priority_cache);
+ if (0 != (*pflags & MHD_USE_TLS))
+ gnutls_priority_deinit (daemon->priority_cache);
#endif /* HTTPS_SUPPORT */
- free (daemon);
- return NULL;
- }
+ free (daemon);
+ return NULL;
}
-
- if (! MHD_mutex_init_ (&daemon->nnc_lock))
+ daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
+ if (NULL == daemon->nnc)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("MHD failed to initialize nonce-nc mutex\n"));
+ _ ("Failed to allocate memory for nonce-nc map: %s\n"),
+ MHD_strerror_ (errno));
#endif
#ifdef HTTPS_SUPPORT
if (0 != (*pflags & MHD_USE_TLS))
- gnutls_priority_deinit (daemon->priority_cache);
+ gnutls_priority_deinit (daemon->priority_cache);
#endif /* HTTPS_SUPPORT */
- free (daemon->nnc);
free (daemon);
return NULL;
}
+ }
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (! MHD_mutex_init_ (&daemon->nnc_lock))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("MHD failed to initialize nonce-nc mutex.\n"));
+#endif
+#ifdef HTTPS_SUPPORT
+ if (0 != (*pflags & MHD_USE_TLS))
+ gnutls_priority_deinit (daemon->priority_cache);
+#endif /* HTTPS_SUPPORT */
+ free (daemon->nnc);
+ free (daemon);
+ return NULL;
+ }
+#endif
#endif
- /* Thread pooling currently works only with internal select thread model */
+ /* Thread polling currently works only with internal select thread mode */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
(daemon->worker_pool_size > 0) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "MHD thread polling only works with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
+#endif
+ goto free_and_fail;
+ }
#endif
+ if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
+ (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ {
+ /* try to open listen socket */
+ int domain;
+
+#ifdef HAVE_INET6
+ domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
+#else /* ! HAVE_INET6 */
+ if (*pflags & MHD_USE_IPv6)
goto free_and_fail;
- }
+ domain = PF_INET;
+#endif /* ! HAVE_INET6 */
-#ifdef __SYMBIAN32__
- if (0 != (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION)))
+ listen_fd = MHD_socket_create_listen_ (domain);
+ if (MHD_INVALID_SOCKET == listen_fd)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("Threaded operations are not supported on Symbian.\n"));
+ _ ("Failed to create socket for listening: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
goto free_and_fail;
}
+
+ /* Apply the socket options according to listening_address_reuse. */
+ if (0 == daemon->listening_address_reuse)
+ {
+#ifndef MHD_WINSOCK_SOCKETS
+ /* No user requirement, use "traditional" default SO_REUSEADDR
+ * on non-W32 platforms, and do not fail if it doesn't work.
+ * Don't use it on W32, because on W32 it will allow multiple
+ * bind to the same address:port, like SO_REUSEPORT on others. */
+ if (0 > setsockopt (listen_fd,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (void*) &on, sizeof (on)))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
- (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ }
+#endif /* ! MHD_WINSOCK_SOCKETS */
+ }
+ else if (daemon->listening_address_reuse > 0)
{
- /* try to open listen socket */
- listen_fd = MHD_socket_create_listen_(*pflags & MHD_USE_IPv6);
- if (MHD_INVALID_SOCKET == listen_fd)
- {
+ /* User requested to allow reusing listening address:port. */
+#ifndef MHD_WINSOCK_SOCKETS
+ /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
+ * it doesn't work. */
+ if (0 > setsockopt (listen_fd,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (void*) &on, sizeof (on)))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to create socket for listening: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- goto free_and_fail;
- }
-
- /* Apply the socket options according to listening_address_reuse. */
- if (0 == daemon->listening_address_reuse)
- {
-#ifndef _WIN32
- /* No user requirement, use "traditional" default SO_REUSEADDR
- * on non-W32 platforms, and do not fail if it doesn't work.
- * Don't use it on W32, because on W32 it will allow multiple
- * bind to the same address:port, like SO_REUSEPORT on others. */
- if (0 > setsockopt (listen_fd,
- SOL_SOCKET,
- SO_REUSEADDR,
- (void*)&on, sizeof (on)))
- {
+ }
+#endif /* ! MHD_WINSOCK_SOCKETS */
+ /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
+ * Fail if SO_REUSEPORT is not defined or setsockopt fails.
+ */
+ /* SO_REUSEADDR on W32 has the same semantics
+ as SO_REUSEPORT on BSD/Linux */
+#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
+ if (0 > setsockopt (listen_fd,
+ SOL_SOCKET,
+#ifndef MHD_WINSOCK_SOCKETS
+ SO_REUSEPORT,
+#else /* MHD_WINSOCK_SOCKETS */
+ SO_REUSEADDR,
+#endif /* MHD_WINSOCK_SOCKETS */
+ (void *) &on,
+ sizeof (on)))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- }
-#endif /* ! _WIN32 */
- }
- else if (daemon->listening_address_reuse > 0)
- {
- /* User requested to allow reusing listening address:port. */
-#ifndef _WIN32
- /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
- * it doesn't work. */
- if (0 > setsockopt (listen_fd,
- SOL_SOCKET,
- SO_REUSEADDR,
- (void*)&on, sizeof (on)))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- }
-#endif /* ! _WIN32 */
- /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
- * Fail if SO_REUSEPORT is not defined or setsockopt fails.
- */
- /* SO_REUSEADDR on W32 has the same semantics
- as SO_REUSEPORT on BSD/Linux */
-#if defined(_WIN32) || defined(SO_REUSEPORT)
- if (0 > setsockopt (listen_fd,
- SOL_SOCKET,
-#ifndef _WIN32
- SO_REUSEPORT,
-#else /* _WIN32 */
- SO_REUSEADDR,
-#endif /* _WIN32 */
- (void *) &on,
- sizeof (on)))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- goto free_and_fail;
- }
-#else /* !_WIN32 && !SO_REUSEPORT */
- /* we're supposed to allow address:port re-use, but
- on this platform we cannot; fail hard */
+ goto free_and_fail;
+ }
+#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
+ /* we're supposed to allow address:port re-use, but
+ on this platform we cannot; fail hard */
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
#endif
- goto free_and_fail;
-#endif /* !_WIN32 && !SO_REUSEPORT */
- }
- else /* if (daemon->listening_address_reuse < 0) */
- {
- /* User requested to disallow reusing listening address:port.
- * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
- * is used and Solaris with SO_EXCLBIND.
- * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
- * or setsockopt fails.
- */
-#if (defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE)) || \
- (defined(__sun) && defined(SO_EXCLBIND))
- if (0 > setsockopt (listen_fd,
- SOL_SOCKET,
+ goto free_and_fail;
+#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
+ }
+ else /* if (daemon->listening_address_reuse < 0) */
+ {
+ /* User requested to disallow reusing listening address:port.
+ * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
+ * is used and Solaris with SO_EXCLBIND.
+ * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
+ * or setsockopt fails.
+ */
+#if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
+ (defined(__sun) && defined(SO_EXCLBIND))
+ if (0 > setsockopt (listen_fd,
+ SOL_SOCKET,
#ifdef SO_EXCLUSIVEADDRUSE
- SO_EXCLUSIVEADDRUSE,
+ SO_EXCLUSIVEADDRUSE,
#else /* SO_EXCLBIND */
- SO_EXCLBIND,
+ SO_EXCLBIND,
#endif /* SO_EXCLBIND */
- (void *) &on,
- sizeof (on)))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- goto free_and_fail;
- }
-#elif defined(_WIN32) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
+ (void *) &on,
+ sizeof (on)))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- goto free_and_fail;
-#endif /* _WIN32 */
- }
+ goto free_and_fail;
+ }
+#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
+#endif
+ goto free_and_fail;
+#endif /* MHD_WINSOCK_SOCKETS */
+ }
- /* check for user supplied sockaddr */
+ /* check for user supplied sockaddr */
#if HAVE_INET6
- if (0 != (*pflags & MHD_USE_IPv6))
- addrlen = sizeof (struct sockaddr_in6);
- else
+ if (0 != (*pflags & MHD_USE_IPv6))
+ addrlen = sizeof (struct sockaddr_in6);
+ else
#endif
- addrlen = sizeof (struct sockaddr_in);
- if (NULL == servaddr)
- {
+ addrlen = sizeof (struct sockaddr_in);
+ if (NULL == servaddr)
+ {
#if HAVE_INET6
- if (0 != (*pflags & MHD_USE_IPv6))
- {
- memset (&servaddr6,
- 0,
- sizeof (struct sockaddr_in6));
- servaddr6.sin6_family = AF_INET6;
- servaddr6.sin6_port = htons (port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
- servaddr6.sin6_len = sizeof (struct sockaddr_in6);
-#endif
- servaddr = (struct sockaddr *) &servaddr6;
- }
- else
-#endif
- {
- memset (&servaddr4,
- 0,
- sizeof (struct sockaddr_in));
- servaddr4.sin_family = AF_INET;
- servaddr4.sin_port = htons (port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
- servaddr4.sin_len = sizeof (struct sockaddr_in);
-#endif
- servaddr = (struct sockaddr *) &servaddr4;
- }
- }
- daemon->listen_fd = listen_fd;
-
if (0 != (*pflags & MHD_USE_IPv6))
- {
+ {
+#ifdef IN6ADDR_ANY_INIT
+ static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
+#endif
+ memset (&servaddr6,
+ 0,
+ sizeof (struct sockaddr_in6));
+ servaddr6.sin6_family = AF_INET6;
+ servaddr6.sin6_port = htons (port);
+#ifdef IN6ADDR_ANY_INIT
+ servaddr6.sin6_addr = static_in6any;
+#endif
+#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
+ servaddr6.sin6_len = sizeof (struct sockaddr_in6);
+#endif
+ servaddr = (struct sockaddr *) &servaddr6;
+ }
+ else
+#endif
+ {
+ memset (&servaddr4,
+ 0,
+ sizeof (struct sockaddr_in));
+ servaddr4.sin_family = AF_INET;
+ servaddr4.sin_port = htons (port);
+ if (0 != INADDR_ANY)
+ servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
+#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+ servaddr4.sin_len = sizeof (struct sockaddr_in);
+#endif
+ servaddr = (struct sockaddr *) &servaddr4;
+ }
+ }
+ daemon->listen_fd = listen_fd;
+ if (0 != (*pflags & MHD_USE_IPv6))
+ {
#ifdef IPPROTO_IPV6
#ifdef IPV6_V6ONLY
- /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
- (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
- and may also be missing on older POSIX systems; good luck if you have any of those,
- your IPv6 socket may then also bind against IPv4 anyway... */
- const MHD_SCKT_OPT_BOOL_ v6_only =
- (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
- if (0 > setsockopt (listen_fd,
- IPPROTO_IPV6, IPV6_V6ONLY,
- (const void *) &v6_only,
- sizeof (v6_only)))
+ /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
+ (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
+ and may also be missing on older POSIX systems; good luck if you have any of those,
+ your IPv6 socket may then also bind against IPv4 anyway... */
+ const MHD_SCKT_OPT_BOOL_ v6_only =
+ (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
+ if (0 > setsockopt (listen_fd,
+ IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *) &v6_only,
+ sizeof (v6_only)))
{
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
}
#endif
#endif
- }
- if (-1 == bind (listen_fd, servaddr, addrlen))
- {
+ }
+ if (-1 == bind (listen_fd, servaddr, addrlen))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to bind to port %u: %s\n"),
- (unsigned int) port,
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Failed to bind to port %u: %s\n"),
+ (unsigned int) port,
+ MHD_socket_last_strerr_ ());
#endif
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
- }
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
#ifdef TCP_FASTOPEN
- if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
+ if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
+ {
+ if (0 == daemon->fastopen_queue_size)
+ daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
+ if (0 != setsockopt (listen_fd,
+ IPPROTO_TCP,
+ TCP_FASTOPEN,
+ (const void*) &daemon->fastopen_queue_size,
+ sizeof (daemon->fastopen_queue_size)))
{
- if (0 == daemon->fastopen_queue_size)
- daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
- if (0 != setsockopt (listen_fd,
- IPPROTO_TCP,
- TCP_FASTOPEN,
- &daemon->fastopen_queue_size,
- sizeof (daemon->fastopen_queue_size)))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("setsockopt failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- }
}
+ }
#endif
- if (listen (listen_fd,
- daemon->listen_backlog_size) < 0)
- {
+ if (listen (listen_fd,
+ daemon->listen_backlog_size) < 0)
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to listen for connections: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Failed to listen for connections: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
- }
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
}
+ }
else
+ {
+ listen_fd = daemon->listen_fd;
+ }
+
+#ifdef HAVE_GETSOCKNAME
+ if ( (0 == daemon->port) &&
+ (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ { /* Get port number. */
+ struct sockaddr_storage bindaddr;
+
+ memset (&bindaddr,
+ 0,
+ sizeof (struct sockaddr_storage));
+ addrlen = sizeof (struct sockaddr_storage);
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+ bindaddr.ss_len = addrlen;
+#endif
+ if (0 != getsockname (listen_fd,
+ (struct sockaddr *) &bindaddr,
+ &addrlen))
{
- listen_fd = daemon->listen_fd;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to get listen port number: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif /* HAVE_MESSAGES */
}
-
- if ( (MHD_INVALID_SOCKET != listen_fd) &&
- (! MHD_socket_nonblocking_ (listen_fd)) )
+#ifdef MHD_POSIX_SOCKETS
+ else if (sizeof (bindaddr) < addrlen)
{
+ /* should be impossible with `struct sockaddr_storage` */
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("Failed to set nonblocking mode on listening socket: %s\n"),
- MHD_socket_last_strerr_());
-#endif
- if (0 != (*pflags & MHD_USE_EPOLL) ||
- daemon->worker_pool_size > 0)
+ _ (
+ "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
+#endif /* HAVE_MESSAGES */
+ }
+#ifndef __linux__
+ else if (0 == addrlen)
+ {
+ /* Many non-Linux-based platforms return zero addrlen
+ * for AF_UNIX sockets */
+ daemon->port = 0; /* special value for UNIX domain sockets */
+ }
+#endif /* __linux__ */
+#endif /* MHD_POSIX_SOCKETS */
+ else
+ {
+ switch (bindaddr.ss_family)
+ {
+ case AF_INET:
{
- /* Accept must be non-blocking. Multiple children may wake up
- * to handle a new connection, but only one will win the race.
- * The others must immediately return. */
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
+ struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
+
+ daemon->port = ntohs (s4->sin_port);
+ break;
+ }
+#ifdef HAVE_INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
+
+ daemon->port = ntohs (s6->sin6_port);
+ mhd_assert (0 != (*pflags & MHD_USE_IPv6));
+ break;
}
+#endif /* HAVE_INET6 */
+#ifdef AF_UNIX
+ case AF_UNIX:
+ daemon->port = 0; /* special value for UNIX domain sockets */
+ break;
+#endif
+ default:
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Unknown address family!\n"));
+#endif
+ daemon->port = 0; /* ugh */
+ break;
+ }
}
+ }
+#endif /* HAVE_GETSOCKNAME */
if ( (MHD_INVALID_SOCKET != listen_fd) &&
- (! MHD_SCKT_FD_FITS_FDSET_(listen_fd,
- NULL)) &&
- (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
- {
+ (! MHD_socket_nonblocking_ (listen_fd)) )
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
- listen_fd,
- FD_SETSIZE);
+ MHD_DLOG (daemon,
+ _ ("Failed to set nonblocking mode on listening socket: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
+ if (0 != (*pflags & MHD_USE_EPOLL)
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ || (daemon->worker_pool_size > 0)
+#endif
+ )
+ {
+ /* Accept must be non-blocking. Multiple children may wake up
+ * to handle a new connection, but only one will win the race.
+ * The others must immediately return. */
MHD_socket_close_chk_ (listen_fd);
goto free_and_fail;
}
+ }
+ if ( (MHD_INVALID_SOCKET != listen_fd) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (listen_fd,
+ NULL)) &&
+ (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Listen socket descriptor (%d) is not " \
+ "less than FD_SETSIZE (%d).\n"),
+ (int) listen_fd,
+ (int) FD_SETSIZE);
+#endif
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
#ifdef EPOLL_SUPPORT
- if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
- (0 == daemon->worker_pool_size) &&
- (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ if ( (0 != (*pflags & MHD_USE_EPOLL))
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ && (0 == daemon->worker_pool_size)
+#endif
+ )
+ {
+ if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
{
- if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
#endif
- goto free_and_fail;
- }
- if (MHD_YES != setup_epoll_to_listen (daemon))
- goto free_and_fail;
+ goto free_and_fail;
}
+ if (MHD_NO == setup_epoll_to_listen (daemon))
+ goto free_and_fail;
+ }
#endif /* EPOLL_SUPPORT */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD failed to initialize IP connection limit mutex\n"));
+ MHD_DLOG (daemon,
+ _ ("MHD failed to initialize IP connection limit mutex.\n"));
#endif
- if (MHD_INVALID_SOCKET != listen_fd)
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
- }
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD failed to initialize IP connection limit mutex\n"));
+ MHD_DLOG (daemon,
+ _ ("MHD failed to initialize IP connection limit mutex.\n"));
+#endif
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
+#endif
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
#endif
- MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
- if (MHD_INVALID_SOCKET != listen_fd)
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
- }
#ifdef HTTPS_SUPPORT
/* initialize HTTPS daemon certificate aspects & send / recv functions */
if ( (0 != (*pflags & MHD_USE_TLS)) &&
(0 != MHD_TLS_init (daemon)) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to initialize TLS support\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to initialize TLS support.\n"));
#endif
- if (MHD_INVALID_SOCKET != listen_fd)
- MHD_socket_close_chk_ (listen_fd);
- MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
- MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
- goto free_and_fail;
- }
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+#endif
+ goto free_and_fail;
+ }
#endif /* HTTPS_SUPPORT */
- if ( ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
- (0 == daemon->worker_pool_size) ) &&
- (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) &&
- (! MHD_create_named_thread_ (&daemon->pid,
- (*pflags & MHD_USE_THREAD_PER_CONNECTION) ?
- "MHD-listen" : "MHD-single",
- daemon->thread_stack_size,
- &MHD_select_thread,
- daemon) ) )
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ /* Start threads if requested by parameters */
+ if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
+ {
+ /* Internal thread (or threads) is used.
+ * Make sure that MHD will be able to communicate with threads. */
+ /* If using a thread pool ITC will be initialised later
+ * for each individual worker thread. */
+#ifdef HAVE_LISTEN_SHUTDOWN
+ mhd_assert ((1 < daemon->worker_pool_size) || \
+ (MHD_ITC_IS_VALID_ (daemon->itc)) || \
+ (MHD_INVALID_SOCKET != daemon->listen_fd));
+#else /* ! HAVE_LISTEN_SHUTDOWN */
+ mhd_assert ((1 < daemon->worker_pool_size) || \
+ (MHD_ITC_IS_VALID_ (daemon->itc)));
+#endif /* ! HAVE_LISTEN_SHUTDOWN */
+ if (0 == daemon->worker_pool_size)
{
+ if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to create listen thread: %s\n"),
- MHD_strerror_ (errno));
+ MHD_DLOG (daemon,
+ _ ("Failed to initialise mutex.\n"));
#endif
- MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
- MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
- if (MHD_INVALID_SOCKET != listen_fd)
- MHD_socket_close_chk_ (listen_fd);
- goto free_and_fail;
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
+ if (! MHD_create_named_thread_ (&daemon->pid,
+ (*pflags
+ & MHD_USE_THREAD_PER_CONNECTION) ?
+ "MHD-listen" : "MHD-single",
+ daemon->thread_stack_size,
+ &MHD_polling_thread,
+ daemon) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to create listen thread: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+ goto free_and_fail;
+ }
}
- if ( (daemon->worker_pool_size > 0) &&
- (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ else /* 0 < daemon->worker_pool_size */
{
/* Coarse-grained count of connections per thread (note error
* due to integer division). Also keep track of how many
@@ -6000,7 +7076,8 @@
unsigned int leftover_conns = daemon->connection_limit
% daemon->worker_pool_size;
- i = 0; /* we need this in case fcntl or malloc fails */
+ mhd_assert (2 <= daemon->worker_pool_size);
+ i = 0; /* we need this in case fcntl or malloc fails */
/* Allocate memory for pooled objects */
daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
@@ -6010,84 +7087,126 @@
/* Start the workers in the pool */
for (i = 0; i < daemon->worker_pool_size; ++i)
- {
- /* Create copy of the Daemon object for each worker */
- struct MHD_Daemon *d = &daemon->worker_pool[i];
+ {
+ /* Create copy of the Daemon object for each worker */
+ struct MHD_Daemon *d = &daemon->worker_pool[i];
- memcpy (d, daemon, sizeof (struct MHD_Daemon));
- /* Adjust pooling params for worker daemons; note that memcpy()
- has already copied MHD_USE_INTERNAL_POLLING_THREAD thread model into
- the worker threads. */
- d->master = daemon;
- d->worker_pool_size = 0;
- d->worker_pool = NULL;
-
- if (0 != (*pflags & MHD_USE_ITC))
- {
- if (! MHD_itc_init_ (d->itc))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to create worker inter-thread communication channel: %s\n"),
- MHD_itc_last_strerror_() );
-#endif
- goto thread_failed;
- }
- if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
- (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc),
- NULL)) )
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
-#endif
- MHD_itc_destroy_chk_ (d->itc);
- goto thread_failed;
- }
- }
- else
- MHD_itc_set_invalid_ (d->itc);
+ memcpy (d, daemon, sizeof (struct MHD_Daemon));
+ /* Adjust polling params for worker daemons; note that memcpy()
+ has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
+ the worker threads. */
+ d->master = daemon;
+ d->worker_pool_size = 0;
+ d->worker_pool = NULL;
+ if (! MHD_mutex_init_ (&d->new_connections_mutex))
+ {
+ #ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to initialise mutex.\n"));
+ #endif
+ goto thread_failed;
+ }
+ if (0 != (*pflags & MHD_USE_ITC))
+ {
+ if (! MHD_itc_init_ (d->itc))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "Failed to create worker inter-thread communication channel: %s\n"),
+ MHD_itc_last_strerror_ () );
+#endif
+ MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
+ goto thread_failed;
+ }
+ if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
+ (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc),
+ NULL)) )
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ (
+ "File descriptor for worker inter-thread communication channel exceeds maximum value.\n"));
+#endif
+ MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
+ MHD_itc_destroy_chk_ (d->itc);
+ goto thread_failed;
+ }
+ }
+ else
+ MHD_itc_set_invalid_ (d->itc);
- /* Divide available connections evenly amongst the threads.
- * Thread indexes in [0, leftover_conns) each get one of the
- * leftover connections. */
- d->connection_limit = conns_per_thread;
- if (i < leftover_conns)
- ++d->connection_limit;
+#ifdef HAVE_LISTEN_SHUTDOWN
+ mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \
+ (MHD_INVALID_SOCKET != d->listen_fd));
+#else /* ! HAVE_LISTEN_SHUTDOWN */
+ mhd_assert (MHD_ITC_IS_VALID_ (d->itc));
+#endif /* ! HAVE_LISTEN_SHUTDOWN */
+
+ /* Divide available connections evenly amongst the threads.
+ * Thread indexes in [0, leftover_conns) each get one of the
+ * leftover connections. */
+ d->connection_limit = conns_per_thread;
+ if (i < leftover_conns)
+ ++d->connection_limit;
#ifdef EPOLL_SUPPORT
- if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
- (MHD_YES != setup_epoll_to_listen (d)) )
- goto thread_failed;
-#endif
- /* Must init cleanup connection mutex for each worker */
- if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("MHD failed to initialize cleanup connection mutex\n"));
-#endif
- goto thread_failed;
- }
-
- /* Spawn the worker thread */
- if (! MHD_create_named_thread_ (&d->pid,
- "MHD-worker",
- daemon->thread_stack_size,
- &MHD_select_thread,
- d))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to create pool thread: %s\n"),
- MHD_strerror_ (errno));
-#endif
- /* Free memory for this worker; cleanup below handles
- * all previously-created workers. */
- MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
- goto thread_failed;
- }
+ if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
+ (MHD_NO == setup_epoll_to_listen (d)) )
+ {
+ if (MHD_ITC_IS_VALID_ (d->itc))
+ MHD_itc_destroy_chk_ (d->itc);
+ MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
+ goto thread_failed;
}
+#endif
+ /* Must init cleanup connection mutex for each worker */
+ if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("MHD failed to initialize cleanup connection mutex.\n"));
+#endif
+ if (MHD_ITC_IS_VALID_ (d->itc))
+ MHD_itc_destroy_chk_ (d->itc);
+ MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
+ goto thread_failed;
+ }
+
+ /* Spawn the worker thread */
+ if (! MHD_create_named_thread_ (&d->pid,
+ "MHD-worker",
+ daemon->thread_stack_size,
+ &MHD_polling_thread,
+ d))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to create pool thread: %s\n"),
+ MHD_strerror_ (errno));
+#endif
+ /* Free memory for this worker; cleanup below handles
+ * all previously-created workers. */
+ MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
+ if (MHD_ITC_IS_VALID_ (d->itc))
+ MHD_itc_destroy_chk_ (d->itc);
+ MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
+ goto thread_failed;
+ }
+ }
+ }
+ }
+ else
+ { /* Daemon without internal threads */
+ if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ _ ("Failed to initialise mutex.\n"));
+#endif
+ goto free_and_fail;
}
+ }
+#endif
#ifdef HTTPS_SUPPORT
/* API promises to never use the password after initialization,
so we additionally NULL it here to not deref a dangling pointer. */
@@ -6096,21 +7215,21 @@
return daemon;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
thread_failed:
/* If no worker threads created, then shut down normally. Calling
MHD_stop_daemon (as we do below) doesn't work here since it
assumes a 0-sized thread pool means we had been in the default
MHD_USE_INTERNAL_POLLING_THREAD mode. */
if (0 == i)
- {
- if (MHD_INVALID_SOCKET != listen_fd)
- MHD_socket_close_chk_ (listen_fd);
- MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
- MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
- if (NULL != daemon->worker_pool)
- free (daemon->worker_pool);
- goto free_and_fail;
- }
+ {
+ if (MHD_INVALID_SOCKET != listen_fd)
+ MHD_socket_close_chk_ (listen_fd);
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+ if (NULL != daemon->worker_pool)
+ free (daemon->worker_pool);
+ goto free_and_fail;
+ }
/* Shutdown worker threads we've already created. Pretend
as though we had fully initialized our daemon, but
@@ -6119,21 +7238,22 @@
daemon->worker_pool_size = i;
MHD_stop_daemon (daemon);
return NULL;
+#endif
- free_and_fail:
+free_and_fail:
/* clean up basic memory state in 'daemon' and return NULL to
indicate failure */
#ifdef EPOLL_SUPPORT
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
if (daemon->upgrade_fd_in_epoll)
- {
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- daemon->epoll_upgrade_fd,
- NULL))
- MHD_PANIC (_("Failed to remove FD from epoll set\n"));
- daemon->upgrade_fd_in_epoll = false;
- }
+ {
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ daemon->epoll_upgrade_fd,
+ NULL))
+ MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
+ daemon->upgrade_fd_in_epoll = false;
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
if (-1 != daemon->epoll_fd)
close (daemon->epoll_fd);
@@ -6144,13 +7264,21 @@
#endif /* EPOLL_SUPPORT */
#ifdef DAUTH_SUPPORT
free (daemon->nnc);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
#endif
+#endif
#ifdef HTTPS_SUPPORT
if (0 != (*pflags & MHD_USE_TLS))
+ {
gnutls_priority_deinit (daemon->priority_cache);
+ if (daemon->x509_cred)
+ gnutls_certificate_free_credentials (daemon->x509_cred);
+ if (daemon->psk_cred)
+ gnutls_psk_free_server_credentials (daemon->psk_cred);
+ }
#endif /* HTTPS_SUPPORT */
- if (MHD_ITC_IS_VALID_(daemon->itc))
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
MHD_itc_destroy_chk_ (daemon->itc);
free (daemon);
return NULL;
@@ -6169,7 +7297,8 @@
close_all_connections (struct MHD_Daemon *daemon)
{
struct MHD_Connection *pos;
- const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
+ const bool used_thr_p_c = (0 != (daemon->options
+ & MHD_USE_THREAD_PER_CONNECTION));
#ifdef UPGRADE_SUPPORT
const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
#endif /* UPGRADE_SUPPORT */
@@ -6177,20 +7306,44 @@
struct MHD_UpgradeResponseHandle *urh;
struct MHD_UpgradeResponseHandle *urhn;
const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
+ MHD_thread_ID_match_current_ (daemon->pid) );
+ mhd_assert (NULL == daemon->worker_pool);
+#endif /* MHD_USE_THREADS */
+ mhd_assert (daemon->shutdown);
+
+#ifdef MHD_USE_THREADS
+/* Remove externally added new connections that are
+ * not processed by the daemon thread. */
+ while (NULL != (pos = daemon->new_connections_tail))
+ {
+ mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
+ DLL_remove (daemon->new_connections_head,
+ daemon->new_connections_tail,
+ pos);
+ new_connection_close_ (daemon, pos);
+ }
+#endif /* MHD_USE_THREADS */
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
/* give upgraded HTTPS connections a chance to finish */
/* 'daemon->urh_head' is not used in thread-per-connection mode. */
for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
- {
- urhn = urh->prev;
- /* call generic forwarding function for passing data
- with chance to detect that application is done. */
- process_urh (urh);
- MHD_connection_finish_forward_ (urh->connection);
- urh->clean_ready = true;
- /* Resuming will move connection to cleanup list. */
- MHD_resume_connection(urh->connection);
- }
+ {
+ mhd_assert (! used_thr_p_c);
+ urhn = urh->prev;
+ /* call generic forwarding function for passing data
+ with chance to detect that application is done. */
+ process_urh (urh);
+ MHD_connection_finish_forward_ (urh->connection);
+ urh->clean_ready = true;
+ /* Resuming will move connection to cleanup list. */
+ MHD_resume_connection (urh->connection);
+ }
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
/* Give suspended connections a chance to resume to avoid
@@ -6198,88 +7351,125 @@
connections left in case of a tight race with a recently
resumed connection. */
if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
- {
- daemon->resuming = true; /* Force check for pending resume. */
- resume_suspended_connections (daemon);
- }
+ {
+ daemon->resuming = true; /* Force check for pending resume. */
+ resume_suspended_connections (daemon);
+ }
/* first, make sure all threads are aware of shutdown; need to
traverse DLLs in peace... */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
#ifdef UPGRADE_SUPPORT
if (upg_allowed)
- {
- struct MHD_Connection * susp;
+ {
+ struct MHD_Connection *susp;
- susp = daemon->suspended_connections_tail;
- while (NULL != susp)
- {
- if (NULL == susp->urh) /* "Upgraded" connection? */
- MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
+ susp = daemon->suspended_connections_tail;
+ while (NULL != susp)
+ {
+ if (NULL == susp->urh) /* "Upgraded" connection? */
+ MHD_PANIC (_ (
+ "MHD_stop_daemon() called while we have suspended connections.\n"));
#ifdef HTTPS_SUPPORT
- else if (used_tls &&
- used_thr_p_c &&
- (! susp->urh->clean_ready) )
- shutdown (susp->urh->app.socket,
- SHUT_RDWR); /* Wake thread by shutdown of app socket. */
+ else if (used_tls &&
+ used_thr_p_c &&
+ (! susp->urh->clean_ready) )
+ shutdown (susp->urh->app.socket,
+ SHUT_RDWR); /* Wake thread by shutdown of app socket. */
#endif /* HTTPS_SUPPORT */
- else
- {
+ else
+ {
#ifdef HAVE_MESSAGES
- if (! susp->urh->was_closed)
- MHD_DLOG (daemon,
- _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
-#endif
- susp->urh->was_closed = true;
- /* If thread-per-connection is used, connection's thread
- * may still processing "upgrade" (exiting). */
- if (! used_thr_p_c)
- MHD_connection_finish_forward_ (susp);
- /* Do not use MHD_resume_connection() as mutex is
- * already locked. */
- susp->resuming = true;
- daemon->resuming = true;
- }
- susp = susp->prev;
- }
+ if (! susp->urh->was_closed)
+ MHD_DLOG (daemon,
+ _ (
+ "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
+#endif
+ susp->urh->was_closed = true;
+ /* If thread-per-connection is used, connection's thread
+ * may still processing "upgrade" (exiting). */
+ if (! used_thr_p_c)
+ MHD_connection_finish_forward_ (susp);
+ /* Do not use MHD_resume_connection() as mutex is
+ * already locked. */
+ susp->resuming = true;
+ daemon->resuming = true;
+ }
+ susp = susp->prev;
}
+ }
else /* This 'else' is combined with next 'if' */
#endif /* UPGRADE_SUPPORT */
if (NULL != daemon->suspended_connections_head)
- MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
+ MHD_PANIC (_ (
+ "MHD_stop_daemon() called while we have suspended connections.\n"));
+#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
+#ifdef MHD_USE_THREADS
+ if (upg_allowed && used_tls && used_thr_p_c)
+ {
+ /* "Upgraded" threads may be running in parallel. Connection will not be
+ * moved to the "cleanup list" until connection's thread finishes.
+ * We must ensure that all "upgraded" connections are finished otherwise
+ * connection may stay in "suspended" list and will not be cleaned. */
+ for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev)
+ {
+ /* Any connection found here is "upgraded" connection, normal suspended
+ * connections are already removed from this list. */
+ mhd_assert (NULL != pos->urh);
+ if (! pos->thread_joined)
+ {
+ /* While "cleanup" list is not manipulated by "upgraded"
+ * connection, "cleanup" mutex is required for call of
+ * MHD_resume_connection() during finishing of "upgraded"
+ * thread. */
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if (! MHD_join_thread_ (pos->pid.handle))
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ pos->thread_joined = true;
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ }
+ }
+ }
+#endif /* MHD_USE_THREADS */
+#endif
for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
- {
- shutdown (pos->socket_fd,
- SHUT_RDWR);
+ {
+ shutdown (pos->socket_fd,
+ SHUT_RDWR);
#if MHD_WINSOCK_SOCKETS
- if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (MHD_ITC_IS_VALID_(daemon->itc)) &&
- (! MHD_itc_activate_ (daemon->itc, "e")) )
- MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
+ if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (MHD_ITC_IS_VALID_ (daemon->itc)) &&
+ (! MHD_itc_activate_ (daemon->itc, "e")) )
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
#endif
- }
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/* now, collect per-connection threads */
if (used_thr_p_c)
+ {
+ pos = daemon->connections_tail;
+ while (NULL != pos)
{
- pos = daemon->connections_tail;
- while (NULL != pos)
+ if (! pos->thread_joined)
{
- if (! pos->thread_joined)
- {
- MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
- if (! MHD_join_thread_ (pos->pid))
- MHD_PANIC (_("Failed to join a thread\n"));
- MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
- pos->thread_joined = true;
- /* The thread may have concurrently modified the DLL,
- need to restart from the beginning */
- pos = daemon->connections_tail;
- continue;
- }
- pos = pos->prev;
+ MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+ if (! MHD_join_thread_ (pos->pid.handle))
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+ pos->thread_joined = true;
+ /* The thread may have concurrently modified the DLL,
+ need to restart from the beginning */
+ pos = daemon->connections_tail;
+ continue;
}
+ pos = pos->prev;
}
+ }
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+#endif
#ifdef UPGRADE_SUPPORT
/* Finished threads with "upgraded" connections need to be moved
@@ -6287,18 +7477,21 @@
/* "Upgraded" connections that were not closed explicitly by
* application should be moved to cleanup list too. */
if (upg_allowed)
- {
- daemon->resuming = true; /* Force check for pending resume. */
- resume_suspended_connections (daemon);
- }
+ {
+ daemon->resuming = true; /* Force check for pending resume. */
+ resume_suspended_connections (daemon);
+ }
#endif /* UPGRADE_SUPPORT */
+ mhd_assert (NULL == daemon->suspended_connections_head);
/* now that we're alone, move everyone to cleanup */
while (NULL != (pos = daemon->connections_tail))
{
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
(! pos->thread_joined) )
- MHD_PANIC (_("Failed to join a thread\n"));
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+#endif
close_connection (pos);
}
MHD_cleanup_connections (daemon);
@@ -6315,132 +7508,170 @@
MHD_stop_daemon (struct MHD_Daemon *daemon)
{
MHD_socket fd;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
unsigned int i;
+#endif
if (NULL == daemon)
return;
-
- if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
- resume_suspended_connections (daemon);
+ if ( (daemon->shutdown) && (NULL == daemon->master) )
+ MHD_PANIC (_ ("MHD_stop_daemon() was called twice."));
+ /* Slave daemons must be stopped by master daemon. */
+ mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) );
daemon->shutdown = true;
- fd = daemon->listen_fd;
+ if (daemon->was_quiesced)
+ fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
+ else
+ fd = daemon->listen_fd;
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (NULL != daemon->worker_pool)
+ { /* Master daemon with worker pool. */
+ mhd_assert (1 < daemon->worker_pool_size);
+ mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
- if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ /* Let workers shutdown in parallel. */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
{
- /* Separate thread(s) is used for select()/poll()/etc. */
- if (NULL != daemon->worker_pool)
- {
- /* Pool of workers is used. */
- /* Initiate shutdown process in wokers. */
- for (i = 0; i < daemon->worker_pool_size; ++i)
- {
- daemon->worker_pool[i].shutdown = true;
- if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
- {
- if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
- MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
- }
+ daemon->worker_pool[i].shutdown = true;
+ if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
+ {
+ if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
+ "e"))
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
+ }
+ else
+ mhd_assert (MHD_INVALID_SOCKET != fd);
+ }
#ifdef HAVE_LISTEN_SHUTDOWN
- else if (MHD_INVALID_SOCKET != fd)
- {
- /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
- /* No problem if shutdown will be called several times for the same socket. */
- (void) shutdown (fd,
- SHUT_RDWR);
- }
-#endif
- }
- /* Start harvesting. */
- for (i = 0; i < daemon->worker_pool_size; ++i)
- {
- if (! MHD_join_thread_ (daemon->worker_pool[i].pid))
- MHD_PANIC (_("Failed to join a thread\n"));
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ (void) shutdown (fd,
+ SHUT_RDWR);
+ }
+#endif /* HAVE_LISTEN_SHUTDOWN */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
+ {
+ MHD_stop_daemon (&daemon->worker_pool[i]);
+ }
+ free (daemon->worker_pool);
+ mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc));
#ifdef EPOLL_SUPPORT
- if (-1 != daemon->worker_pool[i].epoll_fd)
- MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_fd);
+ mhd_assert (-1 == daemon->epoll_fd);
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if (-1 != daemon->worker_pool[i].epoll_upgrade_fd)
- MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_upgrade_fd);
+ mhd_assert (-1 == daemon->epoll_upgrade_fd);
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+ }
+ else
#endif
- if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc) )
- MHD_itc_destroy_chk_ (daemon->worker_pool[i].itc);
- MHD_mutex_destroy_chk_ (&daemon->worker_pool[i].cleanup_connection_mutex);
- }
- free (daemon->worker_pool);
- }
+ { /* Worker daemon or single daemon. */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ { /* Worker daemon or single daemon with internal thread(s). */
+ mhd_assert (0 == daemon->worker_pool_size);
+ /* Separate thread(s) is used for polling sockets. */
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ {
+ if (! MHD_itc_activate_ (daemon->itc,
+ "e"))
+ MHD_PANIC (_ (
+ "Failed to signal shutdown via inter-thread communication channel.\n"));
+ }
else
- {
- /* Single internal thread is used for select()/poll()/etc. */
- if (MHD_ITC_IS_VALID_(daemon->itc))
- {
- if (! MHD_itc_activate_ (daemon->itc, "e"))
- MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
- }
+ {
#ifdef HAVE_LISTEN_SHUTDOWN
- else
- {
- /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
- if ( (MHD_INVALID_SOCKET != fd) &&
- (! daemon->was_quiesced) )
- (void) shutdown (fd,
- SHUT_RDWR);
- }
-#endif
- if (! MHD_join_thread_ (daemon->pid))
- {
- MHD_PANIC (_("Failed to join a thread\n"));
- }
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ if (NULL == daemon->master)
+ (void) shutdown (fd,
+ SHUT_RDWR);
}
+ else
+#endif /* HAVE_LISTEN_SHUTDOWN */
+ mhd_assert (false); /* Should never happen */
+ }
+
+ if (! MHD_join_thread_ (daemon->pid.handle))
+ {
+ MHD_PANIC (_ ("Failed to join a thread.\n"));
+ }
+ /* close_all_connections() was called in daemon thread. */
+ MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
}
- else
+ else
+#endif
{
- /* Internal threads are not used for select()/poll()/etc. */
+ /* No internal threads are used for polling sockets. */
close_all_connections (daemon);
- }
-
- if ( (MHD_INVALID_SOCKET != fd) &&
- (! daemon->was_quiesced) )
- MHD_socket_close_chk_ (fd);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
+#endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
+ }
+ mhd_assert (NULL == daemon->connections_head);
+ mhd_assert (NULL == daemon->cleanup_head);
+ mhd_assert (NULL == daemon->suspended_connections_head);
+ mhd_assert (NULL == daemon->new_connections_head);
+#if defined(UPGRADE_SUPPORT) && defined (HTTPS_SUPPORT)
+ mhd_assert (NULL == daemon->urh_head);
+#endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
- if (MHD_ITC_IS_VALID_ (daemon->itc))
- MHD_itc_destroy_chk_ (daemon->itc);
+ if (MHD_ITC_IS_VALID_ (daemon->itc))
+ MHD_itc_destroy_chk_ (daemon->itc);
#ifdef EPOLL_SUPPORT
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
- (-1 != daemon->epoll_fd) )
- MHD_socket_close_chk_ (daemon->epoll_fd);
+ if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ (-1 != daemon->epoll_fd) )
+ MHD_socket_close_chk_ (daemon->epoll_fd);
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
- (-1 != daemon->epoll_upgrade_fd) )
- MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
+ if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ (-1 != daemon->epoll_upgrade_fd) )
+ MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
#endif
+ }
- /* TLS clean up */
+ if (NULL == daemon->master)
+ { /* Cleanup that should be done only one time in master/single daemon.
+ * Do not perform this cleanup in worker daemons. */
+
+ if (MHD_INVALID_SOCKET != fd)
+ MHD_socket_close_chk_ (fd);
+
+ /* TLS clean up */
#ifdef HTTPS_SUPPORT
- if (daemon->have_dhparams)
+ if (daemon->have_dhparams)
{
gnutls_dh_params_deinit (daemon->https_mem_dhparams);
daemon->have_dhparams = false;
}
- if (0 != (daemon->options & MHD_USE_TLS))
+ if (0 != (daemon->options & MHD_USE_TLS))
{
gnutls_priority_deinit (daemon->priority_cache);
if (daemon->x509_cred)
gnutls_certificate_free_credentials (daemon->x509_cred);
+ if (daemon->psk_cred)
+ gnutls_psk_free_server_credentials (daemon->psk_cred);
}
#endif /* HTTPS_SUPPORT */
#ifdef DAUTH_SUPPORT
- free (daemon->nnc);
- MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
+ free (daemon->nnc);
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
#endif
- MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
- MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
-
- free (daemon);
+#endif
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
+#endif
+ free (daemon);
+ }
}
@@ -6457,47 +7688,51 @@
*/
const union MHD_DaemonInfo *
MHD_get_daemon_info (struct MHD_Daemon *daemon,
- enum MHD_DaemonInfoType info_type,
- ...)
+ enum MHD_DaemonInfoType info_type,
+ ...)
{
if (NULL == daemon)
return NULL;
switch (info_type)
- {
- case MHD_DAEMON_INFO_KEY_SIZE:
- return NULL; /* no longer supported */
- case MHD_DAEMON_INFO_MAC_KEY_SIZE:
- return NULL; /* no longer supported */
- case MHD_DAEMON_INFO_LISTEN_FD:
- return (const union MHD_DaemonInfo *) &daemon->listen_fd;
+ {
+ case MHD_DAEMON_INFO_KEY_SIZE:
+ return NULL; /* no longer supported */
+ case MHD_DAEMON_INFO_MAC_KEY_SIZE:
+ return NULL; /* no longer supported */
+ case MHD_DAEMON_INFO_LISTEN_FD:
+ return (const union MHD_DaemonInfo *) &daemon->listen_fd;
#ifdef EPOLL_SUPPORT
- case MHD_DAEMON_INFO_EPOLL_FD:
- return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
+ case MHD_DAEMON_INFO_EPOLL_FD:
+ return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
#endif
- case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
- if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
- {
- /* Assume that MHD_run() in not called in other thread
- * at the same time. */
- MHD_cleanup_connections (daemon);
- }
- else if (daemon->worker_pool)
- {
- unsigned int i;
- /* Collect the connection information stored in the workers. */
- daemon->connections = 0;
- for (i = 0; i < daemon->worker_pool_size; i++)
- {
- /* FIXME: next line is thread-safe only if read is atomic. */
- daemon->connections += daemon->worker_pool[i].connections;
- }
- }
- return (const union MHD_DaemonInfo *) &daemon->connections;
- case MHD_DAEMON_INFO_FLAGS:
- return (const union MHD_DaemonInfo *) &daemon->options;
- default:
- return NULL;
- };
+ case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
+ if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ {
+ /* Assume that MHD_run() in not called in other thread
+ * at the same time. */
+ MHD_cleanup_connections (daemon);
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ else if (daemon->worker_pool)
+ {
+ unsigned int i;
+ /* Collect the connection information stored in the workers. */
+ daemon->connections = 0;
+ for (i = 0; i < daemon->worker_pool_size; i++)
+ {
+ /* FIXME: next line is thread-safe only if read is atomic. */
+ daemon->connections += daemon->worker_pool[i].connections;
+ }
+ }
+#endif
+ return (const union MHD_DaemonInfo *) &daemon->connections;
+ case MHD_DAEMON_INFO_FLAGS:
+ return (const union MHD_DaemonInfo *) &daemon->options;
+ case MHD_DAEMON_INFO_BIND_PORT:
+ return (const union MHD_DaemonInfo *) &daemon->port;
+ default:
+ return NULL;
+ }
}
@@ -6541,13 +7776,13 @@
static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
if (0 == ver[0])
{
- int res = MHD_snprintf_(ver,
- sizeof(ver),
- "%x.%x.%x",
- (((int)MHD_VERSION >> 24) & 0xFF),
- (((int)MHD_VERSION >> 16) & 0xFF),
- (((int)MHD_VERSION >> 8) & 0xFF));
- if (0 >= res || sizeof(ver) <= res)
+ int res = MHD_snprintf_ (ver,
+ sizeof(ver),
+ "%x.%x.%x",
+ (((int) MHD_VERSION >> 24) & 0xFF),
+ (((int) MHD_VERSION >> 16) & 0xFF),
+ (((int) MHD_VERSION >> 8) & 0xFF));
+ if ((0 >= res) || (sizeof(ver) <= res))
return "0.0.0"; /* Can't return real version*/
}
return ver;
@@ -6566,128 +7801,161 @@
* feature is not supported or feature is unknown.
* @ingroup specialized
*/
-_MHD_EXTERN int
-MHD_is_feature_supported(enum MHD_FEATURE feature)
+enum MHD_Result
+MHD_is_feature_supported (enum MHD_FEATURE feature)
{
- switch(feature)
- {
- case MHD_FEATURE_MESSAGES:
+ switch (feature)
+ {
+ case MHD_FEATURE_MESSAGES:
#ifdef HAVE_MESSAGES
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_TLS:
+ case MHD_FEATURE_TLS:
#ifdef HTTPS_SUPPORT
- return MHD_YES;
+ return MHD_YES;
#else /* ! HTTPS_SUPPORT */
- return MHD_NO;
+ return MHD_NO;
#endif /* ! HTTPS_SUPPORT */
- case MHD_FEATURE_HTTPS_CERT_CALLBACK:
+ case MHD_FEATURE_HTTPS_CERT_CALLBACK:
#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
- return MHD_YES;
+ return MHD_YES;
#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
- return MHD_NO;
+ return MHD_NO;
#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
- case MHD_FEATURE_IPv6:
+ case MHD_FEATURE_HTTPS_CERT_CALLBACK2:
+#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
+ return MHD_YES;
+#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
+ return MHD_NO;
+#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
+ case MHD_FEATURE_IPv6:
#ifdef HAVE_INET6
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_IPv6_ONLY:
+ case MHD_FEATURE_IPv6_ONLY:
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_POLL:
+ case MHD_FEATURE_POLL:
#ifdef HAVE_POLL
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_EPOLL:
+ case MHD_FEATURE_EPOLL:
#ifdef EPOLL_SUPPORT
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
+ case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
#ifdef HAVE_LISTEN_SHUTDOWN
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_SOCKETPAIR:
+ case MHD_FEATURE_SOCKETPAIR:
#ifdef _MHD_ITC_SOCKETPAIR
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_TCP_FASTOPEN:
+ case MHD_FEATURE_TCP_FASTOPEN:
#ifdef TCP_FASTOPEN
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_BASIC_AUTH:
+ case MHD_FEATURE_BASIC_AUTH:
#ifdef BAUTH_SUPPORT
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_DIGEST_AUTH:
+ case MHD_FEATURE_DIGEST_AUTH:
#ifdef DAUTH_SUPPORT
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_POSTPROCESSOR:
+ case MHD_FEATURE_POSTPROCESSOR:
#ifdef HAVE_POSTPROCESSOR
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_HTTPS_KEY_PASSWORD:
+ case MHD_FEATURE_HTTPS_KEY_PASSWORD:
#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
- return MHD_YES;
+ return MHD_YES;
#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
- return MHD_NO;
+ return MHD_NO;
#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
- case MHD_FEATURE_LARGE_FILE:
+ case MHD_FEATURE_LARGE_FILE:
#if defined(HAVE_PREAD64) || defined(_WIN32)
- return MHD_YES;
+ return MHD_YES;
#elif defined(HAVE_PREAD)
- return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
+ return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
#elif defined(HAVE_LSEEK64)
- return MHD_YES;
+ return MHD_YES;
#else
- return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
+ return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
#endif
- case MHD_FEATURE_THREAD_NAMES:
+ case MHD_FEATURE_THREAD_NAMES:
#if defined(MHD_USE_THREAD_NAME_)
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_UPGRADE:
+ case MHD_FEATURE_UPGRADE:
#if defined(UPGRADE_SUPPORT)
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- case MHD_FEATURE_RESPONSES_SHARED_FD:
+ case MHD_FEATURE_RESPONSES_SHARED_FD:
#if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
- return MHD_YES;
+ return MHD_YES;
#else
- return MHD_NO;
+ return MHD_NO;
#endif
- }
+ case MHD_FEATURE_AUTODETECT_BIND_PORT:
+#ifdef MHD_USE_GETSOCKNAME
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE:
+#if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
+ defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_SENDFILE:
+#ifdef _MHD_HAVE_SENDFILE
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+ case MHD_FEATURE_THREADS:
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ return MHD_YES;
+#else
+ return MHD_NO;
+#endif
+
+ }
return MHD_NO;
}
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
#if defined(MHD_USE_POSIX_THREADS)
GCRY_THREAD_OPTION_PTHREAD_IMPL;
@@ -6700,12 +7968,12 @@
if (NULL == *ppmtx)
return ENOMEM;
- if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
- {
- free (*ppmtx);
- *ppmtx = NULL;
- return EPERM;
- }
+ if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
+ {
+ free (*ppmtx);
+ *ppmtx = NULL;
+ return EPERM;
+ }
return 0;
}
@@ -6714,7 +7982,7 @@
static int
gcry_w32_mutex_destroy (void **ppmtx)
{
- int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
+ int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
free (*ppmtx);
return res;
}
@@ -6723,14 +7991,14 @@
static int
gcry_w32_mutex_lock (void **ppmtx)
{
- return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
+ return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
}
static int
gcry_w32_mutex_unlock (void **ppmtx)
{
- return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
+ return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
}
@@ -6738,66 +8006,76 @@
(GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
#endif /* defined(MHD_W32_MUTEX_) */
#endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
-
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
/**
* Initialize do setup work.
*/
void
-MHD_init(void)
+MHD_init (void)
{
-#ifdef _WIN32
+#if defined(MHD_WINSOCK_SOCKETS)
WSADATA wsd;
-#endif /* _WIN32 */
- mhd_panic = &mhd_panic_std;
- mhd_panic_cls = NULL;
-
-#ifdef _WIN32
- if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
- MHD_PANIC (_("Failed to initialize winsock\n"));
+#endif /* MHD_WINSOCK_SOCKETS */
+
+ if (NULL == mhd_panic)
+ mhd_panic = &mhd_panic_std;
+
+#if defined(MHD_WINSOCK_SOCKETS)
+ if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
+ MHD_PANIC (_ ("Failed to initialize winsock.\n"));
mhd_winsock_inited_ = 1;
- if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
- MHD_PANIC (_("Winsock version 2.2 is not available\n"));
-#endif
+ if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
+ MHD_PANIC (_ ("Winsock version 2.2 is not available.\n"));
+#endif /* MHD_WINSOCK_SOCKETS */
#ifdef HTTPS_SUPPORT
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#if GCRYPT_VERSION_NUMBER < 0x010600
#if defined(MHD_USE_POSIX_THREADS)
if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
&gcry_threads_pthread))
- MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
+ MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
#elif defined(MHD_W32_MUTEX_)
if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
&gcry_threads_w32))
- MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
+ MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
#endif /* defined(MHD_W32_MUTEX_) */
gcry_check_version (NULL);
#else
if (NULL == gcry_check_version ("1.6.0"))
- MHD_PANIC (_("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
+ MHD_PANIC (_ (
+ "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
gnutls_global_init ();
#endif /* HTTPS_SUPPORT */
- MHD_monotonic_sec_counter_init();
+ MHD_monotonic_sec_counter_init ();
+ MHD_send_init_static_vars_ ();
+ MHD_init_mem_pools_ ();
}
void
-MHD_fini(void)
+MHD_fini (void)
{
#ifdef HTTPS_SUPPORT
gnutls_global_deinit ();
#endif /* HTTPS_SUPPORT */
-#ifdef _WIN32
+#if defined(MHD_WINSOCK_SOCKETS)
if (mhd_winsock_inited_)
- WSACleanup();
-#endif
- MHD_monotonic_sec_counter_finish();
+ WSACleanup ();
+#endif /* MHD_WINSOCK_SOCKETS */
+ MHD_monotonic_sec_counter_finish ();
}
-_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini);
+
+#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
+_SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini);
+#endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
/* end of daemon.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/digestauth.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2010, 2011, 2012, 2015 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2010, 2011, 2012, 2015, 2018 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,34 +21,77 @@
* @brief Implements HTTP digest authentication
* @author Amr Ali
* @author Matthieu Speder
+ * @author Christian Grothoff (RFC 7616 support)
*/
#include "platform.h"
#include "mhd_limits.h"
#include "internal.h"
#include "md5.h"
+#include "sha256.h"
#include "mhd_mono_clock.h"
#include "mhd_str.h"
#include "mhd_compat.h"
+#include "mhd_assert.h"
-#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
+#if defined(MHD_W32_MUTEX_)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif /* !WIN32_LEAN_AND_MEAN */
#include <windows.h>
-#endif /* _WIN32 && MHD_W32_MUTEX_ */
+#endif /* MHD_W32_MUTEX_ */
-#define HASH_MD5_HEX_LEN (2 * MD5_DIGEST_SIZE)
-/* 32 bit value is 4 bytes */
+/**
+ * 32 bit value is 4 bytes
+ */
#define TIMESTAMP_BIN_SIZE 4
-#define TIMESTAMP_HEX_LEN (2 * TIMESTAMP_BIN_SIZE)
-/* Standard server nonce length, not including terminating null */
-#define NONCE_STD_LEN (HASH_MD5_HEX_LEN + TIMESTAMP_HEX_LEN)
+/**
+ * Standard server nonce length, not including terminating null,
+ *
+ * @param digest_size digest size
+ */
+#define NONCE_STD_LEN(digest_size) \
+ ((digest_size) * 2 + TIMESTAMP_BIN_SIZE * 2)
+
+
+/**
+ * Maximum size of any digest hash supported by MHD.
+ * (SHA-256 > MD5).
+ */
+#define MAX_DIGEST SHA256_DIGEST_SIZE
+
+/**
+ * Macro to avoid using VLAs if the compiler does not support them.
+ */
+#ifndef HAVE_C_VARARRAYS
+/**
+ * Return #MAX_DIGEST.
+ *
+ * @param n length of the digest to be used for a VLA
+ */
+#define VLA_ARRAY_LEN_DIGEST(n) (MAX_DIGEST)
+
+#else
+/**
+ * Return @a n.
+ *
+ * @param n length of the digest to be used for a VLA
+ */
+#define VLA_ARRAY_LEN_DIGEST(n) (n)
+#endif
+
+/**
+ * Check that @a n is below #MAX_NONCE
+ */
+#define VLA_CHECK_LEN_DIGEST(n) do { if ((n) > MAX_DIGEST) mhd_panic ( \
+ mhd_panic_cls, __FILE__, __LINE__, \
+ "VLA too big.\n"); } while (0)
+
/**
* Beginning string for any valid Digest authentication header.
*/
-#define _BASE "Digest "
+#define _BASE "Digest "
/**
* Maximum length of a username for digest authentication.
@@ -63,7 +106,66 @@
/**
* Maximum length of the response in digest authentication.
*/
-#define MAX_AUTH_RESPONSE_LENGTH 128
+#define MAX_AUTH_RESPONSE_LENGTH 256
+
+
+/**
+ * Context passed to functions that need to calculate
+ * a digest but are orthogonal to the specific
+ * algorithm.
+ */
+struct DigestAlgorithm
+{
+ /**
+ * Size of the final digest returned by @e digest.
+ */
+ unsigned int digest_size;
+
+ /**
+ * A context for the digest algorithm, already initialized to be
+ * useful for @e init, @e update and @e digest.
+ */
+ void *ctx;
+
+ /**
+ * Name of the algorithm, "md5" or "sha-256"
+ */
+ const char *alg;
+
+ /**
+ * Buffer of @e digest_size * 2 + 1 bytes.
+ */
+ char *sessionkey;
+
+ /**
+ * Call to initialize @e ctx.
+ */
+ void
+ (*init)(void *ctx);
+
+ /**
+ * Feed more data into the digest function.
+ *
+ * @param ctx context to feed
+ * @param length number of bytes in @a data
+ * @param data data to add
+ */
+ void
+ (*update)(void *ctx,
+ const uint8_t *data,
+ size_t length);
+
+ /**
+ * Compute final @a digest.
+ *
+ * @param ctx context to use
+ * @param[out] digest where to write the result,
+ * must be @e digest_length bytes long
+ */
+ void
+ (*digest)(void *ctx,
+ uint8_t *digest);
+};
/**
@@ -75,195 +177,243 @@
*/
static void
cvthex (const unsigned char *bin,
- size_t len,
- char *hex)
+ size_t len,
+ char *hex)
{
size_t i;
unsigned int j;
for (i = 0; i < len; ++i)
- {
- j = (bin[i] >> 4) & 0x0f;
- hex[i * 2] = (char)((j <= 9) ? (j + '0') : (j - 10 + 'a'));
- j = bin[i] & 0x0f;
- hex[i * 2 + 1] = (char)((j <= 9) ? (j + '0') : (j - 10 + 'a'));
- }
+ {
+ j = (bin[i] >> 4) & 0x0f;
+ hex[i * 2] = (char) ((j <= 9) ? (j + '0') : (j - 10 + 'a'));
+ j = bin[i] & 0x0f;
+ hex[i * 2 + 1] = (char) ((j <= 9) ? (j + '0') : (j - 10 + 'a'));
+ }
hex[len * 2] = '\0';
}
/**
- * calculate H(A1) as per RFC2617 spec and store the
- * result in 'sessionkey'.
+ * calculate H(A1) from given hash as per RFC2617 spec
+ * and store the * result in 'sessionkey'.
*
* @param alg The hash algorithm used, can be "md5" or "md5-sess"
+ * or "sha-256" or "sha-256-sess"
+ * Note that the rest of the code does not support the the "-sess" variants!
+ * @param[in,out] da digest implementation, must match @a alg; the
+ * da->sessionkey will be initialized to the digest in HEX
+ * @param digest An `unsigned char *' pointer to the binary MD5 sum
+ * for the precalculated hash value "username:realm:password"
+ * of #MHD_MD5_DIGEST_SIZE or #MHD_SHA256_DIGEST_SIZE bytes
+ * @param nonce A `char *' pointer to the nonce value
+ * @param cnonce A `char *' pointer to the cnonce value
+ */
+static void
+digest_calc_ha1_from_digest (const char *alg,
+ struct DigestAlgorithm *da,
+ const uint8_t *digest,
+ const char *nonce,
+ const char *cnonce)
+{
+ const unsigned int digest_size = da->digest_size;
+ if ( (MHD_str_equal_caseless_ (alg,
+ "md5-sess")) ||
+ (MHD_str_equal_caseless_ (alg,
+ "sha-256-sess")) )
+ {
+ uint8_t dig[VLA_ARRAY_LEN_DIGEST (digest_size)];
+
+ VLA_CHECK_LEN_DIGEST (digest_size);
+ da->init (da->ctx);
+ da->update (da->ctx,
+ digest,
+ MHD_MD5_DIGEST_SIZE);
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) nonce,
+ strlen (nonce));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) cnonce,
+ strlen (cnonce));
+ da->digest (da->ctx,
+ dig);
+ cvthex (dig,
+ digest_size,
+ da->sessionkey);
+ }
+ else
+ {
+ cvthex (digest,
+ digest_size,
+ da->sessionkey);
+ }
+}
+
+
+/**
+ * calculate H(A1) from username, realm and password as per RFC2617 spec
+ * and store the result in 'sessionkey'.
+ *
+ * @param alg The hash algorithm used, can be "md5" or "md5-sess"
+ * or "sha-256" or "sha-256-sess"
* @param username A `char *' pointer to the username value
* @param realm A `char *' pointer to the realm value
* @param password A `char *' pointer to the password value
* @param nonce A `char *' pointer to the nonce value
* @param cnonce A `char *' pointer to the cnonce value
- * @param sessionkey pointer to buffer of HASH_MD5_HEX_LEN+1 bytes
+ * @param[in,out] da digest algorithm to use, and where to write
+ * the sessionkey to
*/
static void
-digest_calc_ha1 (const char *alg,
- const char *username,
- const char *realm,
- const char *password,
- const char *nonce,
- const char *cnonce,
- char sessionkey[HASH_MD5_HEX_LEN + 1])
+digest_calc_ha1_from_user (const char *alg,
+ const char *username,
+ const char *realm,
+ const char *password,
+ const char *nonce,
+ const char *cnonce,
+ struct DigestAlgorithm *da)
{
- struct MD5Context md5;
- unsigned char ha1[MD5_DIGEST_SIZE];
+ unsigned char ha1[VLA_ARRAY_LEN_DIGEST (da->digest_size)];
- MD5Init (&md5);
- MD5Update (&md5,
- (const unsigned char *) username,
- strlen (username));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) realm,
- strlen (realm));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) password,
- strlen (password));
- MD5Final (ha1,
- &md5);
- if (MHD_str_equal_caseless_(alg,
- "md5-sess"))
- {
- MD5Init (&md5);
- MD5Update (&md5,
- (const unsigned char *) ha1,
- sizeof (ha1));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) nonce,
- strlen (nonce));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) cnonce,
- strlen (cnonce));
- MD5Final (ha1,
- &md5);
- }
- cvthex (ha1,
- sizeof (ha1),
- sessionkey);
+ VLA_CHECK_LEN_DIGEST (da->digest_size);
+ da->init (da->ctx);
+ da->update (da->ctx,
+ (const unsigned char *) username,
+ strlen (username));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) realm,
+ strlen (realm));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) password,
+ strlen (password));
+ da->digest (da->ctx,
+ ha1);
+ digest_calc_ha1_from_digest (alg,
+ da,
+ ha1,
+ nonce,
+ cnonce);
}
/**
- * Calculate request-digest/response-digest as per RFC2617 spec
+ * Calculate request-digest/response-digest as per RFC2617 / RFC7616
+ * spec.
*
- * @param ha1 H(A1)
+ * @param ha1 H(A1), twice the @a da->digest_size + 1 bytes (0-terminated),
+ * MUST NOT be aliased with `da->sessionkey`!
* @param nonce nonce from server
* @param noncecount 8 hex digits
* @param cnonce client nonce
- * @param qop qop-value: "", "auth" or "auth-int"
+ * @param qop qop-value: "", "auth" or "auth-int" (NOTE: only 'auth' is supported today.)
* @param method method from request
* @param uri requested URL
* @param hentity H(entity body) if qop="auth-int"
- * @param response request-digest or response-digest
+ * @param[in,out] da digest algorithm to use, also
+ * we write da->sessionkey (set to response request-digest or response-digest)
*/
static void
-digest_calc_response (const char ha1[HASH_MD5_HEX_LEN + 1],
- const char *nonce,
- const char *noncecount,
- const char *cnonce,
- const char *qop,
- const char *method,
- const char *uri,
- const char *hentity,
- char response[HASH_MD5_HEX_LEN + 1])
+digest_calc_response (const char *ha1,
+ const char *nonce,
+ const char *noncecount,
+ const char *cnonce,
+ const char *qop,
+ const char *method,
+ const char *uri,
+ const char *hentity,
+ struct DigestAlgorithm *da)
{
- struct MD5Context md5;
- unsigned char ha2[MD5_DIGEST_SIZE];
- unsigned char resphash[MD5_DIGEST_SIZE];
- char ha2hex[HASH_MD5_HEX_LEN + 1];
-
- MD5Init (&md5);
- MD5Update (&md5,
- (const unsigned char *) method,
- strlen (method));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) uri,
- strlen (uri));
+ const unsigned int digest_size = da->digest_size;
+ unsigned char ha2[VLA_ARRAY_LEN_DIGEST (digest_size)];
+ unsigned char resphash[VLA_ARRAY_LEN_DIGEST (digest_size)];
+ (void) hentity; /* Unused. Silence compiler warning. */
+
+ VLA_CHECK_LEN_DIGEST (digest_size);
+ da->init (da->ctx);
+ da->update (da->ctx,
+ (const unsigned char *) method,
+ strlen (method));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) uri,
+ strlen (uri));
#if 0
- if (0 == strcasecmp(qop,
- "auth-int"))
- {
- /* This is dead code since the rest of this module does
- not support auth-int. */
- MD5Update (&md5,
- ":",
- 1);
- if (NULL != hentity)
- MD5Update (&md5,
- hentity,
- strlen (hentity));
- }
+ if (0 == strcasecmp (qop,
+ "auth-int"))
+ {
+ /* This is dead code since the rest of this module does
+ not support auth-int. */
+ da->update (da->ctx,
+ ":",
+ 1);
+ if (NULL != hentity)
+ da->update (da->ctx,
+ hentity,
+ strlen (hentity));
+ }
#endif
- MD5Final (ha2,
- &md5);
+ da->digest (da->ctx,
+ ha2);
cvthex (ha2,
- MD5_DIGEST_SIZE,
- ha2hex);
- MD5Init (&md5);
+ digest_size,
+ da->sessionkey);
+ da->init (da->ctx);
/* calculate response */
- MD5Update (&md5,
- (const unsigned char *) ha1,
- HASH_MD5_HEX_LEN);
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) nonce,
- strlen (nonce));
- MD5Update (&md5,
- (const unsigned char*) ":",
- 1);
+ da->update (da->ctx,
+ (const unsigned char *) ha1,
+ digest_size * 2);
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) nonce,
+ strlen (nonce));
+ da->update (da->ctx,
+ (const unsigned char*) ":",
+ 1);
if ('\0' != *qop)
- {
- MD5Update (&md5,
- (const unsigned char *) noncecount,
- strlen (noncecount));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) cnonce,
- strlen (cnonce));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) qop,
- strlen (qop));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- }
- MD5Update (&md5,
- (const unsigned char *) ha2hex,
- HASH_MD5_HEX_LEN);
- MD5Final (resphash,
- &md5);
+ {
+ da->update (da->ctx,
+ (const unsigned char *) noncecount,
+ strlen (noncecount));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) cnonce,
+ strlen (cnonce));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) qop,
+ strlen (qop));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ }
+ da->update (da->ctx,
+ (const unsigned char *) da->sessionkey,
+ digest_size * 2);
+ da->digest (da->ctx,
+ resphash);
cvthex (resphash,
- sizeof(resphash),
- response);
+ digest_size,
+ da->sessionkey);
}
@@ -283,9 +433,9 @@
*/
static size_t
lookup_sub_value (char *dest,
- size_t size,
- const char *data,
- const char *key)
+ size_t size,
+ const char *data,
+ const char *key)
{
size_t keylen;
size_t len;
@@ -300,67 +450,67 @@
keylen = strlen (key);
ptr = data;
while ('\0' != *ptr)
+ {
+ if (NULL == (eq = strchr (ptr,
+ '=')))
+ return 0;
+ q1 = eq + 1;
+ while (' ' == *q1)
+ q1++;
+ if ('\"' != *q1)
+ {
+ q2 = strchr (q1,
+ ',');
+ qn = q2;
+ }
+ else
+ {
+ q1++;
+ q2 = strchr (q1,
+ '\"');
+ if (NULL == q2)
+ return 0; /* end quote not found */
+ qn = q2 + 1;
+ }
+ if ( (MHD_str_equal_caseless_n_ (ptr,
+ key,
+ keylen)) &&
+ (eq == &ptr[keylen]) )
{
- if (NULL == (eq = strchr (ptr,
- '=')))
- return 0;
- q1 = eq + 1;
- while (' ' == *q1)
- q1++;
- if ('\"' != *q1)
- {
- q2 = strchr (q1,
- ',');
- qn = q2;
- }
+ if (NULL == q2)
+ {
+ len = strlen (q1) + 1;
+ if (size > len)
+ size = len;
+ size--;
+ memcpy (dest,
+ q1,
+ size);
+ dest[size] = '\0';
+ return size;
+ }
else
- {
- q1++;
- q2 = strchr (q1,
- '\"');
- if (NULL == q2)
- return 0; /* end quote not found */
- qn = q2 + 1;
- }
- if ( (MHD_str_equal_caseless_n_(ptr,
- key,
- keylen)) &&
- (eq == &ptr[keylen]) )
- {
- if (NULL == q2)
- {
- len = strlen (q1) + 1;
- if (size > len)
- size = len;
- size--;
- strncpy (dest,
- q1,
- size);
- dest[size] = '\0';
- return size;
- }
- else
- {
- if (size > (size_t) ((q2 - q1) + 1))
- size = (q2 - q1) + 1;
- size--;
- memcpy (dest,
- q1,
- size);
- dest[size] = '\0';
- return size;
- }
- }
- if (NULL == qn)
- return 0;
- ptr = strchr (qn,
- ',');
- if (NULL == ptr)
- return 0;
- ptr++;
- while (' ' == *ptr)
- ptr++;
+ {
+ if (size > (size_t) ((q2 - q1) + 1))
+ size = (q2 - q1) + 1;
+ size--;
+ memcpy (dest,
+ q1,
+ size);
+ dest[size] = '\0';
+ return size;
+ }
}
+ if (NULL == qn)
+ return 0;
+ ptr = strchr (qn,
+ ',');
+ if (NULL == ptr)
+ return 0;
+ ptr++;
+ while (' ' == *ptr)
+ ptr++;
+ }
return 0;
}
@@ -374,18 +524,20 @@
* @param nc The nonce counter, zero to add the nonce to the array
* @return #MHD_YES if successful, #MHD_NO if invalid (or we have no NC array)
*/
-static int
+static enum MHD_Result
check_nonce_nc (struct MHD_Connection *connection,
- const char *nonce,
- uint64_t nc)
+ const char *nonce,
+ uint64_t nc)
{
struct MHD_Daemon *daemon = connection->daemon;
struct MHD_NonceNc *nn;
uint32_t off;
uint32_t mod;
const char *np;
+ size_t noncelen;
- if (MAX_NONCE_LENGTH <= strlen (nonce))
+ noncelen = strlen (nonce) + 1;
+ if (MAX_NONCE_LENGTH < noncelen)
return MHD_NO; /* This should be impossible, but static analysis
tools have a hard time with it *and* this also
protects against unsafe modifications that may
@@ -397,10 +549,10 @@
off = 0;
np = nonce;
while ('\0' != *np)
- {
- off = (off << 8) | (*np ^ (off >> 24));
- np++;
- }
+ {
+ off = (off << 8) | (*np ^ (off >> 24));
+ np++;
+ }
off = off % mod;
/*
* Look for the nonce, if it does exist and its corresponding
@@ -408,49 +560,61 @@
* then only increase the nonce counter by one.
*/
nn = &daemon->nnc[off];
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&daemon->nnc_lock);
+#endif
if (0 == nc)
- {
- /* Fresh nonce, reinitialize array */
- strcpy (nn->nonce,
- nonce);
- nn->nc = 0;
- nn->nmask = 0;
- MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
- return MHD_YES;
- }
+ {
+ /* Fresh nonce, reinitialize array */
+ memcpy (nn->nonce,
+ nonce,
+ noncelen);
+ nn->nc = 0;
+ nn->nmask = 0;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
+#endif
+ return MHD_YES;
+ }
/* Note that we use 64 here, as we do not store the
bit for 'nn->nc' itself in 'nn->nmask' */
if ( (nc < nn->nc) &&
(nc + 64 > nc /* checking for overflow */) &&
(nc + 64 >= nn->nc) &&
(0 == ((1LLU << (nn->nc - nc - 1)) & nn->nmask)) )
- {
- /* Out-of-order nonce, but within 64-bit bitmask, set bit */
- nn->nmask |= (1LLU < (nn->nc - nc - 1));
- MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
- return MHD_YES;
- }
+ {
+ /* Out-of-order nonce, but within 64-bit bitmask, set bit */
+ nn->nmask |= (1LLU << (nn->nc - nc - 1));
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
+#endif
+ return MHD_YES;
+ }
if ( (nc <= nn->nc) ||
(0 != strcmp (nn->nonce,
nonce)) )
- {
- /* Nonce does not match, fail */
- MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
+ {
+ /* Nonce does not match, fail */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
+#endif
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
/* Nonce is larger, shift bitmask and bump limit */
if (64 > nc - nn->nc)
- nn->nmask <<= (nc - nn->nc); /* small jump, less than mask width */
+ nn->nmask <<= (nc - nn->nc); /* small jump, less than mask width */
else
- nn->nmask = 0; /* big jump, unset all bits in the mask */
+ nn->nmask = 0; /* big jump, unset all bits in the mask */
nn->nc = nc;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
+#endif
return MHD_YES;
}
@@ -460,30 +624,33 @@
*
* @param connection The MHD connection structure
* @return NULL if no username could be found, a pointer
- * to the username if found
+ * to the username if found
+ * @warning Returned value must be freed by #MHD_free().
* @ingroup authentication
*/
char *
-MHD_digest_auth_get_username(struct MHD_Connection *connection)
+MHD_digest_auth_get_username (struct MHD_Connection *connection)
{
- size_t len;
char user[MAX_USERNAME_LENGTH];
const char *header;
- if (NULL == (header =
- MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_AUTHORIZATION)))
+ if (MHD_NO == MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_AUTHORIZATION,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_AUTHORIZATION),
+ &header,
+ NULL))
return NULL;
if (0 != strncmp (header,
_BASE,
MHD_STATICSTR_LEN_ (_BASE)))
return NULL;
header += MHD_STATICSTR_LEN_ (_BASE);
- if (0 == (len = lookup_sub_value (user,
- sizeof (user),
- header,
- "username")))
+ if (0 == lookup_sub_value (user,
+ sizeof (user),
+ header,
+ "username"))
return NULL;
return strdup (user);
}
@@ -500,66 +667,66 @@
* @param rnd_size The size of the random seed array @a rnd
* @param uri HTTP URI (in MHD, without the arguments ("?k=v")
* @param realm A string of characters that describes the realm of auth.
- * @param nonce A pointer to a character array for the nonce to put in
+ * @param da digest algorithm to use
+ * @param[out] nonce A pointer to a character array for the nonce to put in,
+ * must provide NONCE_STD_LEN(da->digest_size)+1 bytes
*/
static void
calculate_nonce (uint32_t nonce_time,
- const char *method,
- const char *rnd,
- size_t rnd_size,
- const char *uri,
- const char *realm,
- char nonce[NONCE_STD_LEN + 1])
+ const char *method,
+ const char *rnd,
+ size_t rnd_size,
+ const char *uri,
+ const char *realm,
+ struct DigestAlgorithm *da,
+ char *nonce)
{
- struct MD5Context md5;
unsigned char timestamp[TIMESTAMP_BIN_SIZE];
- unsigned char tmpnonce[MD5_DIGEST_SIZE];
- char timestamphex[TIMESTAMP_HEX_LEN + 1];
+ const unsigned int digest_size = da->digest_size;
+ unsigned char tmpnonce[VLA_ARRAY_LEN_DIGEST (digest_size)];
- MD5Init (&md5);
- timestamp[0] = (unsigned char)((nonce_time & 0xff000000) >> 0x18);
- timestamp[1] = (unsigned char)((nonce_time & 0x00ff0000) >> 0x10);
- timestamp[2] = (unsigned char)((nonce_time & 0x0000ff00) >> 0x08);
- timestamp[3] = (unsigned char)((nonce_time & 0x000000ff));
- MD5Update (&md5,
- timestamp,
- sizeof (timestamp));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) method,
- strlen (method));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
+ VLA_CHECK_LEN_DIGEST (digest_size);
+ da->init (da->ctx);
+ timestamp[0] = (unsigned char) ((nonce_time & 0xff000000) >> 0x18);
+ timestamp[1] = (unsigned char) ((nonce_time & 0x00ff0000) >> 0x10);
+ timestamp[2] = (unsigned char) ((nonce_time & 0x0000ff00) >> 0x08);
+ timestamp[3] = (unsigned char) ((nonce_time & 0x000000ff));
+ da->update (da->ctx,
+ timestamp,
+ sizeof (timestamp));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) method,
+ strlen (method));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
if (rnd_size > 0)
- MD5Update (&md5,
- (const unsigned char *) rnd,
- rnd_size);
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) uri,
- strlen (uri));
- MD5Update (&md5,
- (const unsigned char *) ":",
- 1);
- MD5Update (&md5,
- (const unsigned char *) realm,
- strlen (realm));
- MD5Final (tmpnonce,
- &md5);
+ da->update (da->ctx,
+ (const unsigned char *) rnd,
+ rnd_size);
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) uri,
+ strlen (uri));
+ da->update (da->ctx,
+ (const unsigned char *) ":",
+ 1);
+ da->update (da->ctx,
+ (const unsigned char *) realm,
+ strlen (realm));
+ da->digest (da->ctx,
+ tmpnonce);
cvthex (tmpnonce,
- sizeof (tmpnonce),
+ digest_size,
nonce);
cvthex (timestamp,
sizeof (timestamp),
- timestamphex);
- strncat (nonce,
- timestamphex,
- 8);
+ nonce + digest_size * 2);
}
@@ -569,36 +736,46 @@
*
* @param connection the connection
* @param key the key
+ * @param key_size number of bytes in @a key
* @param value the value, can be NULL
+ * @param value_size number of bytes in @a value
* @param kind type of the header
* @return #MHD_YES if the key-value pair is in the headers,
* #MHD_NO if not
*/
-static int
+static enum MHD_Result
test_header (struct MHD_Connection *connection,
- const char *key,
- const char *value,
- enum MHD_ValueKind kind)
+ const char *key,
+ size_t key_size,
+ const char *value,
+ size_t value_size,
+ enum MHD_ValueKind kind)
{
struct MHD_HTTP_Header *pos;
for (pos = connection->headers_received; NULL != pos; pos = pos->next)
- {
- if (kind != pos->kind)
- continue;
- if (0 != strcmp (key,
- pos->header))
- continue;
- if ( (NULL == value) &&
- (NULL == pos->value) )
- return MHD_YES;
- if ( (NULL == value) ||
- (NULL == pos->value) ||
- (0 != strcmp (value,
- pos->value)) )
- continue;
+ {
+ if (kind != pos->kind)
+ continue;
+ if (key_size != pos->header_size)
+ continue;
+ if (value_size != pos->value_size)
+ continue;
+ if (0 != memcmp (key,
+ pos->header,
+ key_size))
+ continue;
+ if ( (NULL == value) &&
+ (NULL == pos->value) )
return MHD_YES;
- }
+ if ( (NULL == value) ||
+ (NULL == pos->value) ||
+ (0 != memcmp (value,
+ pos->value,
+ value_size)) )
+ continue;
+ return MHD_YES;
+ }
return MHD_NO;
}
@@ -613,44 +790,46 @@
* @return #MHD_YES if the arguments match,
* #MHD_NO if not
*/
-static int
+static enum MHD_Result
check_argument_match (struct MHD_Connection *connection,
- const char *args)
+ const char *args)
{
struct MHD_HTTP_Header *pos;
char *argb;
unsigned int num_headers;
- int ret;
+ enum MHD_Result ret;
argb = strdup (args);
if (NULL == argb)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to allocate memory for copy of URI arguments\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to allocate memory for copy of URI arguments.\n"));
#endif /* HAVE_MESSAGES */
- return MHD_NO;
- }
+ return MHD_NO;
+ }
ret = MHD_parse_arguments_ (connection,
- MHD_GET_ARGUMENT_KIND,
- argb,
- &test_header,
- &num_headers);
+ MHD_GET_ARGUMENT_KIND,
+ argb,
+ &test_header,
+ &num_headers);
free (argb);
- if (MHD_YES != ret)
+ if (MHD_NO == ret)
+ {
return MHD_NO;
+ }
/* also check that the number of headers matches */
for (pos = connection->headers_received; NULL != pos; pos = pos->next)
- {
- if (MHD_GET_ARGUMENT_KIND != pos->kind)
- continue;
- num_headers--;
- }
+ {
+ if (MHD_GET_ARGUMENT_KIND != pos->kind)
+ continue;
+ num_headers--;
+ }
if (0 != num_headers)
- {
- /* argument count mismatch */
- return MHD_NO;
- }
+ {
+ /* argument count mismatch */
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -659,47 +838,60 @@
* Authenticates the authorization header sent by the client
*
* @param connection The MHD connection structure
+ * @param[in,out] da digest algorithm to use for checking (written to as
+ * part of the calculations, but the values left in the struct
+ * are not actually expected to be useful for the caller)
* @param realm The realm presented to the client
* @param username The username needs to be authenticated
* @param password The password used in the authentication
+ * @param digest An optional binary hash
+ * of the precalculated hash value "username:realm:password"
+ * (must contain "da->digest_size" bytes or be NULL)
* @param nonce_timeout The amount of time for a nonce to be
- * invalid in seconds
+ * invalid in seconds
* @return #MHD_YES if authenticated, #MHD_NO if not,
- * #MHD_INVALID_NONCE if nonce is invalid
+ * #MHD_INVALID_NONCE if nonce is invalid
* @ingroup authentication
*/
-int
-MHD_digest_auth_check (struct MHD_Connection *connection,
- const char *realm,
- const char *username,
- const char *password,
- unsigned int nonce_timeout)
+static int
+digest_auth_check_all (struct MHD_Connection *connection,
+ struct DigestAlgorithm *da,
+ const char *realm,
+ const char *username,
+ const char *password,
+ const uint8_t *digest,
+ unsigned int nonce_timeout)
{
struct MHD_Daemon *daemon = connection->daemon;
size_t len;
const char *header;
char nonce[MAX_NONCE_LENGTH];
char cnonce[MAX_NONCE_LENGTH];
+ const unsigned int digest_size = da->digest_size;
+ char ha1[VLA_ARRAY_LEN_DIGEST (digest_size) * 2 + 1];
char qop[15]; /* auth,auth-int */
char nc[20];
char response[MAX_AUTH_RESPONSE_LENGTH];
const char *hentity = NULL; /* "auth-int" is not supported */
- char ha1[HASH_MD5_HEX_LEN + 1];
- char respexp[HASH_MD5_HEX_LEN + 1];
- char noncehashexp[NONCE_STD_LEN + 1];
+ char noncehashexp[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (digest_size)) + 1];
uint32_t nonce_time;
uint32_t t;
size_t left; /* number of characters left in 'header' for 'uri' */
uint64_t nci;
+ char *qmark;
- header = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_AUTHORIZATION);
- if (NULL == header)
+ VLA_CHECK_LEN_DIGEST (digest_size);
+ if (MHD_NO == MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_AUTHORIZATION,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_AUTHORIZATION),
+ &header,
+ NULL))
return MHD_NO;
if (0 != strncmp (header,
_BASE,
- MHD_STATICSTR_LEN_(_BASE)))
+ MHD_STATICSTR_LEN_ (_BASE)))
return MHD_NO;
header += MHD_STATICSTR_LEN_ (_BASE);
left = strlen (header);
@@ -708,11 +900,11 @@
char un[MAX_USERNAME_LENGTH];
len = lookup_sub_value (un,
- sizeof (un),
- header,
+ sizeof (un),
+ header,
"username");
if ( (0 == len) ||
- (0 != strcmp (username,
+ (0 != strcmp (username,
un)) )
return MHD_NO;
left -= strlen ("username") + len;
@@ -726,15 +918,15 @@
header,
"realm");
if ( (0 == len) ||
- (0 != strcmp (realm,
+ (0 != strcmp (realm,
r)) )
return MHD_NO;
left -= strlen ("realm") + len;
}
if (0 == (len = lookup_sub_value (nonce,
- sizeof (nonce),
- header,
+ sizeof (nonce),
+ header,
"nonce")))
return MHD_NO;
left -= strlen ("nonce") + len;
@@ -749,18 +941,18 @@
header value. */
return MHD_NO;
}
- if (TIMESTAMP_HEX_LEN !=
- MHD_strx_to_uint32_n_ (nonce + len - TIMESTAMP_HEX_LEN,
- TIMESTAMP_HEX_LEN,
+ if (TIMESTAMP_BIN_SIZE * 2 !=
+ MHD_strx_to_uint32_n_ (nonce + len - TIMESTAMP_BIN_SIZE * 2,
+ TIMESTAMP_BIN_SIZE * 2,
&nonce_time))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Authentication failed, invalid timestamp format.\n"));
+ MHD_DLOG (daemon,
+ _ ("Authentication failed, invalid timestamp format.\n"));
#endif
- return MHD_NO;
- }
- t = (uint32_t) MHD_monotonic_sec_counter();
+ return MHD_NO;
+ }
+ t = (uint32_t) MHD_monotonic_sec_counter ();
/*
* First level vetting for the nonce validity: if the timestamp
* attached to the nonce exceeds `nonce_timeout', then the nonce is
@@ -768,10 +960,10 @@
*/
if ( (t > nonce_time + nonce_timeout) ||
(nonce_time + nonce_timeout < nonce_time) )
- {
- /* too old */
- return MHD_INVALID_NONCE;
- }
+ {
+ /* too old */
+ return MHD_INVALID_NONCE;
+ }
calculate_nonce (nonce_time,
connection->method,
@@ -779,6 +971,7 @@
daemon->digest_auth_rand_size,
connection->url,
realm,
+ da,
noncehashexp);
/*
* Second level vetting for the nonce validity
@@ -789,11 +982,11 @@
* not, the nonce fabrication process going to be
* very hard to achieve.
*/
-
- if (0 != strcmp (nonce, noncehashexp))
- {
- return MHD_INVALID_NONCE;
- }
+ if (0 != strcmp (nonce,
+ noncehashexp))
+ {
+ return MHD_INVALID_NONCE;
+ }
if ( (0 == lookup_sub_value (cnonce,
sizeof (cnonce),
header,
@@ -809,41 +1002,41 @@
(0 == (len = lookup_sub_value (nc,
sizeof (nc),
header,
- "nc")) ) ||
+ "nc")) ) ||
(0 == lookup_sub_value (response,
sizeof (response),
header,
"response")) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Authentication failed, invalid format.\n"));
+ MHD_DLOG (daemon,
+ _ ("Authentication failed, invalid format.\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
if (len != MHD_strx_to_uint64_n_ (nc,
len,
&nci))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Authentication failed, invalid nc format.\n"));
+ MHD_DLOG (daemon,
+ _ ("Authentication failed, invalid nc format.\n"));
#endif
- return MHD_NO; /* invalid nonce format */
- }
+ return MHD_NO; /* invalid nonce format */
+ }
/*
* Checking if that combination of nonce and nc is sound
* and not a replay attack attempt. Also adds the nonce
* to the nonce-nc map if it does not exist there.
*/
- if (MHD_YES !=
+ if (MHD_NO ==
check_nonce_nc (connection,
nonce,
nci))
- {
- return MHD_NO;
- }
+ {
+ return MHD_NO;
+ }
{
char *uri;
@@ -852,8 +1045,8 @@
if (NULL == uri)
{
#ifdef HAVE_MESSAGES
- MHD_DLOG(daemon,
- _("Failed to allocate memory for auth header processing\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to allocate memory for auth header processing.\n"));
#endif /* HAVE_MESSAGES */
return MHD_NO;
}
@@ -865,70 +1058,280 @@
free (uri);
return MHD_NO;
}
-
- digest_calc_ha1 ("md5",
- username,
- realm,
- password,
- nonce,
- cnonce,
- ha1);
+ if (NULL != digest)
+ {
+ /* This will initialize da->sessionkey (ha1) */
+ digest_calc_ha1_from_digest (da->alg,
+ da,
+ digest,
+ nonce,
+ cnonce);
+ }
+ else
+ {
+ /* This will initialize da->sessionkey (ha1) */
+ mhd_assert (NULL != password); /* NULL == digest => password != NULL */
+ digest_calc_ha1_from_user (da->alg,
+ username,
+ realm,
+ password,
+ nonce,
+ cnonce,
+ da);
+ }
+ memcpy (ha1,
+ da->sessionkey,
+ digest_size * 2 + 1);
+ /* This will initialize da->sessionkey (respexp) */
digest_calc_response (ha1,
- nonce,
- nc,
- cnonce,
- qop,
- connection->method,
- uri,
- hentity,
- respexp);
+ nonce,
+ nc,
+ cnonce,
+ qop,
+ connection->method,
+ uri,
+ hentity,
+ da);
+ qmark = strchr (uri,
+ '?');
+ if (NULL != qmark)
+ *qmark = '\0';
/* Need to unescape URI before comparing with connection->url */
daemon->unescape_callback (daemon->unescape_callback_cls,
connection,
uri);
- if (0 != strncmp (uri,
- connection->url,
- strlen (connection->url)))
+ if (0 != strcmp (uri,
+ connection->url))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
- _("Authentication failed, URI does not match.\n"));
+ _ ("Authentication failed, URI does not match.\n"));
#endif
free (uri);
return MHD_NO;
}
{
- const char *args = strchr (uri,
- '?');
+ const char *args = qmark;
if (NULL == args)
- args = "";
+ args = "";
else
- args++;
- if (MHD_YES !=
- check_argument_match (connection,
- args) )
+ args++;
+ if (MHD_NO ==
+ check_argument_match (connection,
+ args) )
{
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Authentication failed, arguments do not match.\n"));
+ MHD_DLOG (daemon,
+ _ ("Authentication failed, arguments do not match.\n"));
#endif
- free (uri);
- return MHD_NO;
+ free (uri);
+ return MHD_NO;
}
}
free (uri);
- return (0 == strcmp(response,
- respexp))
- ? MHD_YES
- : MHD_NO;
+ return (0 == strcmp (response,
+ da->sessionkey))
+ ? MHD_YES
+ : MHD_NO;
}
}
/**
+ * Authenticates the authorization header sent by the client.
+ * Uses #MHD_DIGEST_ALG_MD5 (for now, for backwards-compatibility).
+ * Note that this MAY change to #MHD_DIGEST_ALG_AUTO in the future.
+ * If you want to be sure you get MD5, use #MHD_digest_auth_check2
+ * and specify MD5 explicitly.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param password The password used in the authentication
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const char *password,
+ unsigned int nonce_timeout)
+{
+ return MHD_digest_auth_check2 (connection,
+ realm,
+ username,
+ password,
+ nonce_timeout,
+ MHD_DIGEST_ALG_MD5);
+}
+
+
+/**
+ * Setup digest authentication data structures (on the
+ * stack, hence must be done inline!). Initializes a
+ * "struct DigestAlgorithm da" for algorithm @a algo.
+ *
+ * @param algo digest algorithm to provide
+ * @param da data structure to setup
+ */
+#define SETUP_DA(algo,da) \
+ union { \
+ struct MD5Context md5; \
+ struct sha256_ctx sha256; \
+ } ctx; \
+ union { \
+ char md5[MD5_DIGEST_SIZE * 2 + 1]; \
+ char sha256[SHA256_DIGEST_SIZE * 2 + 1]; \
+ } skey; \
+ struct DigestAlgorithm da; \
+ \
+ do { \
+ switch (algo) { \
+ case MHD_DIGEST_ALG_MD5: \
+ da.digest_size = MD5_DIGEST_SIZE; \
+ da.ctx = &ctx.md5; \
+ da.alg = "md5"; \
+ da.sessionkey = skey.md5; \
+ da.init = &MHD_MD5Init; \
+ da.update = &MHD_MD5Update; \
+ da.digest = &MHD_MD5Final; \
+ break; \
+ case MHD_DIGEST_ALG_AUTO: \
+ /* auto == SHA256, fall-though thus intentional! */ \
+ case MHD_DIGEST_ALG_SHA256: \
+ da.digest_size = SHA256_DIGEST_SIZE; \
+ da.ctx = &ctx.sha256; \
+ da.alg = "sha-256"; \
+ da.sessionkey = skey.sha256; \
+ da.init = &MHD_SHA256_init; \
+ da.update = &MHD_SHA256_update; \
+ da.digest = &sha256_finish; \
+ break; \
+ default: \
+ mhd_assert (false); \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param password The password used in the authentication
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @param algo digest algorithms allowed for verification
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const char *password,
+ unsigned int nonce_timeout,
+ enum MHD_DigestAuthAlgorithm algo)
+{
+ SETUP_DA (algo, da);
+
+ mhd_assert (NULL != password);
+ return digest_auth_check_all (connection,
+ &da,
+ realm,
+ username,
+ password,
+ NULL,
+ nonce_timeout);
+}
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param digest An `unsigned char *' pointer to the binary MD5 sum
+ * for the precalculated hash value "username:realm:password"
+ * of #MHD_MD5_DIGEST_SIZE bytes
+ * @param digest_size number of bytes in @a digest
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @param algo digest algorithms allowed for verification
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check_digest2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const uint8_t *digest,
+ size_t digest_size,
+ unsigned int nonce_timeout,
+ enum MHD_DigestAuthAlgorithm algo)
+{
+ SETUP_DA (algo, da);
+
+ mhd_assert (NULL != digest);
+ if (da.digest_size != digest_size)
+ MHD_PANIC (_ ("Digest size mismatch.\n")); /* API violation! */
+ return digest_auth_check_all (connection,
+ &da,
+ realm,
+ username,
+ NULL,
+ digest,
+ nonce_timeout);
+}
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ * Uses #MHD_DIGEST_ALG_MD5 (required, as @a digest is of fixed
+ * size).
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param digest An `unsigned char *' pointer to the binary digest
+ * for the precalculated hash value "username:realm:password"
+ * of @a digest_size bytes
+ * @param nonce_timeout The amount of time for a nonce to be
+ * invalid in seconds
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * #MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ */
+_MHD_EXTERN int
+MHD_digest_auth_check_digest (struct MHD_Connection *connection,
+ const char *realm,
+ const char *username,
+ const uint8_t digest[MHD_MD5_DIGEST_SIZE],
+ unsigned int nonce_timeout)
+{
+ return MHD_digest_auth_check_digest2 (connection,
+ realm,
+ username,
+ digest,
+ MHD_MD5_DIGEST_SIZE,
+ nonce_timeout,
+ MHD_DIGEST_ALG_MD5);
+}
+
+
+/**
* Queues a response to request authentication from the client
*
* @param connection The MHD connection structure
@@ -938,98 +1341,148 @@
* body; note that this function will set the "WWW Authenticate"
* header and that the caller should not do this
* @param signal_stale #MHD_YES if the nonce is invalid to add
- * 'stale=true' to the authentication header
+ * 'stale=true' to the authentication header
+ * @param algo digest algorithm to use
* @return #MHD_YES on success, #MHD_NO otherwise
* @ingroup authentication
*/
-int
-MHD_queue_auth_fail_response (struct MHD_Connection *connection,
- const char *realm,
- const char *opaque,
- struct MHD_Response *response,
- int signal_stale)
+enum MHD_Result
+MHD_queue_auth_fail_response2 (struct MHD_Connection *connection,
+ const char *realm,
+ const char *opaque,
+ struct MHD_Response *response,
+ int signal_stale,
+ enum MHD_DigestAuthAlgorithm algo)
{
int ret;
int hlen;
- char nonce[NONCE_STD_LEN + 1];
+ SETUP_DA (algo, da);
- /* Generating the server nonce */
- calculate_nonce ((uint32_t) MHD_monotonic_sec_counter(),
- connection->method,
- connection->daemon->digest_auth_random,
- connection->daemon->digest_auth_rand_size,
- connection->url,
- realm,
- nonce);
- if (MHD_YES !=
- check_nonce_nc (connection,
- nonce,
- 0))
+ {
+ char nonce[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (da.digest_size)) + 1];
+
+ VLA_CHECK_LEN_DIGEST (da.digest_size);
+ /* Generating the server nonce */
+ calculate_nonce ((uint32_t) MHD_monotonic_sec_counter (),
+ connection->method,
+ connection->daemon->digest_auth_random,
+ connection->daemon->digest_auth_rand_size,
+ connection->url,
+ realm,
+ &da,
+ nonce);
+ if (MHD_NO ==
+ check_nonce_nc (connection,
+ nonce,
+ 0))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (connection->daemon,
- _("Could not register nonce (is the nonce array size zero?).\n"));
+ _ (
+ "Could not register nonce (is the nonce array size zero?).\n"));
#endif
return MHD_NO;
}
- /* Building the authentication header */
- hlen = MHD_snprintf_ (NULL,
- 0,
- "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
- realm,
- nonce,
- opaque,
- signal_stale
- ? ",stale=\"true\""
- : "");
- if (hlen > 0)
+ /* Building the authentication header */
+ hlen = MHD_snprintf_ (NULL,
+ 0,
+ "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s",
+ realm,
+ nonce,
+ opaque,
+ da.alg,
+ signal_stale
+ ? ",stale=\"true\""
+ : "");
+ if (hlen > 0)
{
char *header;
- header = MHD_calloc_ (1, hlen + 1);
+ header = MHD_calloc_ (1,
+ hlen + 1);
if (NULL == header)
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG(connection->daemon,
- _("Failed to allocate memory for auth response header\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to allocate memory for auth response header.\n"));
#endif /* HAVE_MESSAGES */
- return MHD_NO;
- }
+ return MHD_NO;
+ }
if (MHD_snprintf_ (header,
hlen + 1,
- "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s",
+ "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\",algorithm=%s%s",
realm,
nonce,
opaque,
+ da.alg,
signal_stale
? ",stale=\"true\""
: "") == hlen)
- ret = MHD_add_response_header(response,
- MHD_HTTP_HEADER_WWW_AUTHENTICATE,
- header);
+ ret = MHD_add_response_header (response,
+ MHD_HTTP_HEADER_WWW_AUTHENTICATE,
+ header);
else
ret = MHD_NO;
+#if 0
+ if ( (MHD_NO != ret) && (AND in state : 100 continue aborting ...))
+ ret = MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close");
+#endif
free (header);
}
- else
- ret = MHD_NO;
+ else
+ ret = MHD_NO;
+ }
- if (MHD_YES == ret)
- {
- ret = MHD_queue_response (connection,
- MHD_HTTP_UNAUTHORIZED,
- response);
- }
+ if (MHD_NO != ret)
+ {
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ response);
+ }
else
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (connection->daemon,
- _("Failed to add Digest auth header\n"));
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to add Digest auth header.\n"));
#endif /* HAVE_MESSAGES */
- }
+ }
return ret;
}
+/**
+ * Queues a response to request authentication from the client.
+ * For now uses MD5 (for backwards-compatibility). Still, if you
+ * need to be sure, use #MHD_queue_fail_auth_response2().
+ *
+ * @param connection The MHD connection structure
+ * @param realm the realm presented to the client
+ * @param opaque string to user for opaque value
+ * @param response reply to send; should contain the "access denied"
+ * body; note that this function will set the "WWW Authenticate"
+ * header and that the caller should not do this
+ * @param signal_stale #MHD_YES if the nonce is invalid to add
+ * 'stale=true' to the authentication header
+ * @return #MHD_YES on success, #MHD_NO otherwise
+ * @ingroup authentication
+ */
+enum MHD_Result
+MHD_queue_auth_fail_response (struct MHD_Connection *connection,
+ const char *realm,
+ const char *opaque,
+ struct MHD_Response *response,
+ int signal_stale)
+{
+ return MHD_queue_auth_fail_response2 (connection,
+ realm,
+ opaque,
+ response,
+ signal_stale,
+ MHD_DIGEST_ALG_MD5);
+}
+
+
/* end of digestauth.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/internal.c
^
|
@@ -36,53 +36,53 @@
MHD_state_to_string (enum MHD_CONNECTION_STATE state)
{
switch (state)
- {
- case MHD_CONNECTION_INIT:
- return "connection init";
- case MHD_CONNECTION_URL_RECEIVED:
- return "connection url received";
- case MHD_CONNECTION_HEADER_PART_RECEIVED:
- return "header partially received";
- case MHD_CONNECTION_HEADERS_RECEIVED:
- return "headers received";
- case MHD_CONNECTION_HEADERS_PROCESSED:
- return "headers processed";
- case MHD_CONNECTION_CONTINUE_SENDING:
- return "continue sending";
- case MHD_CONNECTION_CONTINUE_SENT:
- return "continue sent";
- case MHD_CONNECTION_BODY_RECEIVED:
- return "body received";
- case MHD_CONNECTION_FOOTER_PART_RECEIVED:
- return "footer partially received";
- case MHD_CONNECTION_FOOTERS_RECEIVED:
- return "footers received";
- case MHD_CONNECTION_HEADERS_SENDING:
- return "headers sending";
- case MHD_CONNECTION_HEADERS_SENT:
- return "headers sent";
- case MHD_CONNECTION_NORMAL_BODY_READY:
- return "normal body ready";
- case MHD_CONNECTION_NORMAL_BODY_UNREADY:
- return "normal body unready";
- case MHD_CONNECTION_CHUNKED_BODY_READY:
- return "chunked body ready";
- case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
- return "chunked body unready";
- case MHD_CONNECTION_BODY_SENT:
- return "body sent";
- case MHD_CONNECTION_FOOTERS_SENDING:
- return "footers sending";
- case MHD_CONNECTION_FOOTERS_SENT:
- return "footers sent";
- case MHD_CONNECTION_CLOSED:
- return "closed";
- case MHD_TLS_CONNECTION_INIT:
- return "secure connection init";
- default:
- return "unrecognized connection state";
- }
+ {
+ case MHD_CONNECTION_INIT:
+ return "connection init";
+ case MHD_CONNECTION_URL_RECEIVED:
+ return "connection url received";
+ case MHD_CONNECTION_HEADER_PART_RECEIVED:
+ return "header partially received";
+ case MHD_CONNECTION_HEADERS_RECEIVED:
+ return "headers received";
+ case MHD_CONNECTION_HEADERS_PROCESSED:
+ return "headers processed";
+ case MHD_CONNECTION_CONTINUE_SENDING:
+ return "continue sending";
+ case MHD_CONNECTION_CONTINUE_SENT:
+ return "continue sent";
+ case MHD_CONNECTION_BODY_RECEIVED:
+ return "body received";
+ case MHD_CONNECTION_FOOTER_PART_RECEIVED:
+ return "footer partially received";
+ case MHD_CONNECTION_FOOTERS_RECEIVED:
+ return "footers received";
+ case MHD_CONNECTION_HEADERS_SENDING:
+ return "headers sending";
+ case MHD_CONNECTION_HEADERS_SENT:
+ return "headers sent";
+ case MHD_CONNECTION_NORMAL_BODY_READY:
+ return "normal body ready";
+ case MHD_CONNECTION_NORMAL_BODY_UNREADY:
+ return "normal body unready";
+ case MHD_CONNECTION_CHUNKED_BODY_READY:
+ return "chunked body ready";
+ case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
+ return "chunked body unready";
+ case MHD_CONNECTION_BODY_SENT:
+ return "body sent";
+ case MHD_CONNECTION_FOOTERS_SENDING:
+ return "footers sending";
+ case MHD_CONNECTION_FOOTERS_SENT:
+ return "footers sent";
+ case MHD_CONNECTION_CLOSED:
+ return "closed";
+ default:
+ return "unrecognized connection state";
+ }
}
+
+
#endif
#endif
@@ -107,6 +107,8 @@
va);
va_end (va);
}
+
+
#endif
@@ -120,7 +122,7 @@
{
char *p;
- for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
+ for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
*p = ' ';
}
@@ -141,30 +143,30 @@
char *wpos = val;
while ('\0' != *rpos)
+ {
+ uint32_t num;
+ switch (*rpos)
{
- uint32_t num;
- switch (*rpos)
- {
- case '%':
- if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
- 2,
- &num))
- {
- *wpos = (char)((unsigned char) num);
- wpos++;
- rpos += 3;
- break;
- }
- /* TODO: add bad sequence handling */
- /* intentional fall through! */
- default:
- *wpos = *rpos;
- wpos++;
- rpos++;
- }
+ case '%':
+ if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
+ 2,
+ &num))
+ {
+ *wpos = (char) ((unsigned char) num);
+ wpos++;
+ rpos += 3;
+ break;
+ }
+ /* TODO: add bad sequence handling */
+ /* intentional fall through! */
+ default:
+ *wpos = *rpos;
+ wpos++;
+ rpos++;
}
+ }
*wpos = '\0'; /* add 0-terminator */
- return wpos - val; /* = strlen(val) */
+ return wpos - val;
}
@@ -174,7 +176,7 @@
*
* @param kind header kind to pass to @a cb
* @param connection connection to add headers to
- * @param[in|out] args argument URI string (after "?" in URI),
+ * @param[in,out] args argument URI string (after "?" in URI),
* clobbered in the process!
* @param cb function to call on each key-value pair found
* @param[out] num_headers set to the number of headers found
@@ -182,12 +184,12 @@
* #MHD_YES for success (parsing succeeded, @a cb always
* returned #MHD_YES)
*/
-int
+enum MHD_Result
MHD_parse_arguments_ (struct MHD_Connection *connection,
- enum MHD_ValueKind kind,
- char *args,
- MHD_ArgumentIterator_ cb,
- unsigned int *num_headers)
+ enum MHD_ValueKind kind,
+ char *args,
+ MHD_ArgumentIterator_ cb,
+ unsigned int *num_headers)
{
struct MHD_Daemon *daemon = connection->daemon;
char *equals;
@@ -195,89 +197,100 @@
*num_headers = 0;
while ( (NULL != args) &&
- ('\0' != args[0]) )
+ ('\0' != args[0]) )
+ {
+ size_t key_len;
+ size_t value_len;
+ equals = strchr (args, '=');
+ amper = strchr (args, '&');
+ if (NULL == amper)
{
- equals = strchr (args, '=');
- amper = strchr (args, '&');
- if (NULL == amper)
- {
- /* last argument */
- if (NULL == equals)
- {
- /* last argument, without '=' */
- MHD_unescape_plus (args);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- args);
- if (MHD_YES != cb (connection,
- args,
- NULL,
- kind))
- return MHD_NO;
- (*num_headers)++;
- break;
- }
- /* got 'foo=bar' */
- equals[0] = '\0';
- equals++;
- MHD_unescape_plus (args);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- args);
- MHD_unescape_plus (equals);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- equals);
- if (MHD_YES != cb (connection,
- args,
- equals,
- kind))
- return MHD_NO;
- (*num_headers)++;
- break;
- }
- /* amper is non-NULL here */
- amper[0] = '\0';
- amper++;
- if ( (NULL == equals) ||
- (equals >= amper) )
- {
- /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
- MHD_unescape_plus (args);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- args);
- if (MHD_YES != cb (connection,
- args,
- NULL,
- kind))
- return MHD_NO;
- /* continue with 'bar' */
- (*num_headers)++;
- args = amper;
- continue;
- }
- /* equals and amper are non-NULL here, and equals < amper,
- so we got regular 'foo=value&bar...'-kind of argument */
+ /* last argument */
+ if (NULL == equals)
+ {
+ /* last argument, without '=' */
+ MHD_unescape_plus (args);
+ key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ args);
+ if (MHD_NO == cb (connection,
+ args,
+ key_len,
+ NULL,
+ 0,
+ kind))
+ return MHD_NO;
+ (*num_headers)++;
+ break;
+ }
+ /* got 'foo=bar' */
equals[0] = '\0';
equals++;
MHD_unescape_plus (args);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- args);
+ key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ args);
MHD_unescape_plus (equals);
- daemon->unescape_callback (daemon->unescape_callback_cls,
- connection,
- equals);
- if (MHD_YES != cb (connection,
- args,
- equals,
- kind))
+ value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ equals);
+ if (MHD_NO == cb (connection,
+ args,
+ key_len,
+ equals,
+ value_len,
+ kind))
return MHD_NO;
(*num_headers)++;
+ break;
+ }
+ /* amper is non-NULL here */
+ amper[0] = '\0';
+ amper++;
+ if ( (NULL == equals) ||
+ (equals >= amper) )
+ {
+ /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
+ MHD_unescape_plus (args);
+ key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ args);
+ if (MHD_NO == cb (connection,
+ args,
+ key_len,
+ NULL,
+ 0,
+ kind))
+ return MHD_NO;
+ /* continue with 'bar' */
+ (*num_headers)++;
args = amper;
+ continue;
}
+ /* equals and amper are non-NULL here, and equals < amper,
+ so we got regular 'foo=value&bar...'-kind of argument */
+ equals[0] = '\0';
+ equals++;
+ MHD_unescape_plus (args);
+ key_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ args);
+ MHD_unescape_plus (equals);
+ value_len = daemon->unescape_callback (daemon->unescape_callback_cls,
+ connection,
+ equals);
+ if (MHD_NO == cb (connection,
+ args,
+ key_len,
+ equals,
+ value_len,
+ kind))
+ return MHD_NO;
+ (*num_headers)++;
+ args = amper;
+ }
return MHD_YES;
}
+
/* end of internal.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/internal.h
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,8 @@
#include "mhd_options.h"
#include "platform.h"
#include "microhttpd.h"
+#include "mhd_assert.h"
+
#ifdef HTTPS_SUPPORT
#include <gnutls/gnutls.h>
#if GNUTLS_VERSION_MAJOR >= 3
@@ -53,43 +55,82 @@
*
* @param msg error message (const char *)
*/
-#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); BUILTIN_NOT_REACHED; } while (0)
+#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); \
+ BUILTIN_NOT_REACHED; } while (0)
#else
/**
* Trigger 'panic' action based on fatal errors.
*
* @param msg error message (const char *)
*/
-#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0)
+#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); \
+ BUILTIN_NOT_REACHED; } while (0)
#endif
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
#include "mhd_threads.h"
+#endif
#include "mhd_locks.h"
#include "mhd_sockets.h"
#include "mhd_itc_types.h"
/**
+ * @def _MHD_MACRO_NO
+ * "Negative answer"/"false" for use in macros, meaningful for precompiler
+ */
+#define _MHD_MACRO_NO 0
+
+/**
+ * @def _MHD_MACRO_YES
+ * "Positive answer"/"true" for use in macros, meaningful for precompiler
+ */
+#define _MHD_MACRO_YES 1
+
+/**
* Close FD and abort execution if error is detected.
* @param fd the FD to close
*/
-#define MHD_fd_close_chk_(fd) do { \
- if (0 == close ((fd)) && (EBADF == errno)) \
- MHD_PANIC(_("Failed to close FD.\n")); \
- } while(0)
+#define MHD_fd_close_chk_(fd) do { \
+ if ( (0 != close ((fd)) && (EBADF == errno)) ) { \
+ MHD_PANIC (_ ("Failed to close FD.\n")); \
+ } \
+} while (0)
+
+/*
+#define EXTRA_CHECKS _MHD_MACRO_NO
+ * Not used. Behaviour is controlled by _DEBUG/NDEBUG macros.
+ */
+
+#ifndef _MHD_DEBUG_CONNECT
+/**
+ * Print extra messages when establishing
+ * connections? (only adds non-error messages).
+ */
+#define _MHD_DEBUG_CONNECT _MHD_MACRO_NO
+#endif /* ! _MHD_DEBUG_CONNECT */
+
+#ifndef _MHD_DEBUG_SEND_DATA
+/**
+ * Should all data send be printed to stderr?
+ */
+#define _MHD_DEBUG_SEND_DATA _MHD_MACRO_NO
+#endif /* ! _MHD_DEBUG_SEND_DATA */
+#ifndef _MHD_DEBUG_CLOSE
/**
- * Should we perform additional sanity checks at runtime (on our internal
- * invariants)? This may lead to aborts, but can be useful for debugging.
+ * Add extra debug messages with reasons for closing connections
+ * (non-error reasons).
*/
-#define EXTRA_CHECKS MHD_NO
+#define _MHD_DEBUG_CLOSE _MHD_MACRO_NO
+#endif /* ! _MHD_DEBUG_CLOSE */
#define MHD_MAX(a,b) (((a)<(b)) ? (b) : (a))
#define MHD_MIN(a,b) (((a)<(b)) ? (a) : (b))
/**
- * Minimum size by which MHD tries to increment read/write buffers.
+ * Minimum reasonable size by which MHD tries to increment read/write buffers.
* We usually begin with half the available pool space for the
* IO-buffer, but if absolutely needed we additively grow by the
* number of bytes given here (up to -- theoretically -- the full pool
@@ -109,10 +150,11 @@
extern void *mhd_panic_cls;
/* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */
-#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-#define BUILTIN_NOT_REACHED __builtin_unreachable()
+#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= \
+ 5)
+#define BUILTIN_NOT_REACHED __builtin_unreachable ()
#elif defined(_MSC_FULL_VER)
-#define BUILTIN_NOT_REACHED __assume(0)
+#define BUILTIN_NOT_REACHED __assume (0)
#else
#define BUILTIN_NOT_REACHED
#endif
@@ -121,11 +163,24 @@
/**
* Determine length of static string / macro strings at compile time.
*/
-#define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1)
+#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
#endif /* ! MHD_STATICSTR_LEN_ */
/**
+ * Tri-state on/off/unknown
+ */
+enum MHD_tristate
+{
+ _MHD_UNKNOWN = -1, /**< State is not yet checked nor set */
+ _MHD_OFF = false, /**< State is "off" / "disabled" */
+ _MHD_NO = false, /**< State is "off" / "disabled" */
+ _MHD_ON = true, /**< State is "on" / "enabled" */
+ _MHD_YES = true /**< State is "on" / "enabled" */
+};
+
+
+/**
* State of the socket with respect to epoll (bitmask).
*/
enum MHD_EpollState
@@ -205,8 +260,8 @@
#define MHD_TEST_ALLOW_SUSPEND_RESUME 8192
/**
- * Maximum length of a nonce in digest authentication. 32(MD5 Hex) +
- * 8(Timestamp Hex) + 1(NULL); hence 41 should suffice, but Opera
+ * Maximum length of a nonce in digest authentication. 64(SHA-256 Hex) +
+ * 8(Timestamp Hex) + 1(NULL); hence 73 should suffice, but Opera
* (already) takes more (see Mantis #1633), so we've increased the
* value to support something longer...
*/
@@ -246,8 +301,9 @@
*/
void
MHD_DLOG (const struct MHD_Daemon *daemon,
- const char *format,
+ const char *format,
...);
+
#endif
@@ -267,11 +323,21 @@
char *header;
/**
+ * Number of bytes in @a header.
+ */
+ size_t header_size;
+
+ /**
* The value of the header.
*/
char *value;
/**
+ * Number of bytes in @a value.
+ */
+ size_t value_size;
+
+ /**
* Type of the header (where in the HTTP protocol is this header
* from).
*/
@@ -280,6 +346,60 @@
};
+#if defined(MHD_WINSOCK_SOCKETS)
+/**
+ * Internally used I/O vector type for use with winsock.
+ * Binary matches system "WSABUF".
+ */
+typedef struct _MHD_W32_iovec
+{
+ unsigned long iov_len;
+ char *iov_base;
+} MHD_iovec_;
+#define MHD_IOV_ELMN_MAX_SIZE ULONG_MAX
+typedef unsigned long MHD_iov_size_;
+#elif defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
+/**
+ * Internally used I/O vector type for use when writev or sendmsg
+ * is available. Matches system "struct iovec".
+ */
+typedef struct iovec MHD_iovec_;
+#define MHD_IOV_ELMN_MAX_SIZE SIZE_MAX
+typedef size_t MHD_iov_size_;
+#else
+/**
+ * Internally used I/O vector type for use when writev or sendmsg
+ * is not available.
+ */
+typedef struct MHD_IoVec MHD_iovec_;
+#define MHD_IOV_ELMN_MAX_SIZE SIZE_MAX
+typedef size_t MHD_iov_size_;
+#endif
+
+
+struct MHD_iovec_track_
+{
+ /**
+ * The copy of array of iovec elements.
+ * The copy of elements are updated during sending.
+ * The number of elements is not changed during lifetime.
+ */
+ MHD_iovec_ *iov;
+
+ /**
+ * The number of elements in @iov.
+ * This value is not changed during lifetime.
+ */
+ size_t cnt;
+
+ /**
+ * The number of sent elements.
+ * At the same time, it is the index of the next (or current) element
+ * to send.
+ */
+ size_t sent;
+};
+
/**
* Representation of a response.
*/
@@ -331,11 +451,13 @@
void *upgrade_handler_cls;
#endif /* UPGRADE_SUPPORT */
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
* Mutex to synchronize access to @e data, @e size and
* @e reference_count.
*/
MHD_mutex_ mutex;
+#endif
/**
* Set to #MHD_SIZE_UNKNOWN if size is not known.
@@ -360,7 +482,7 @@
size_t data_size;
/**
- * Size of the data buffer @e data.
+ * Size of the writable data buffer @e data.
*/
size_t data_buffer_size;
@@ -380,6 +502,20 @@
*/
enum MHD_ResponseFlags flags;
+ /**
+ * If the @e fd is a pipe (no sendfile()).
+ */
+ bool is_pipe;
+
+ /**
+ * I/O vector used with MHD_create_response_from_iovec.
+ */
+ MHD_iovec_ *data_iov;
+
+ /**
+ * Number of elements in data_iov.
+ */
+ unsigned int data_iovcnt;
};
@@ -505,32 +641,34 @@
*/
MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1,
- /**
- * 20: This connection is finished (only to be freed)
- */
- MHD_CONNECTION_IN_CLEANUP = MHD_CONNECTION_CLOSED + 1,
-
- /*
- * SSL/TLS connection states
- */
-
- /**
- * The initial connection state for all secure connectoins
- * Handshake messages will be processed in this state & while
- * in the #MHD_TLS_HELLO_REQUEST state
- */
- MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1,
-
#ifdef UPGRADE_SUPPORT
/**
* Connection was "upgraded" and socket is now under the
* control of the application.
*/
- MHD_CONNECTION_UPGRADE = MHD_TLS_CONNECTION_INIT + 1,
+ MHD_CONNECTION_UPGRADE
#endif /* UPGRADE_SUPPORT */
};
+
+/**
+ * States of TLS transport layer.
+ */
+enum MHD_TLS_CONN_STATE
+{
+ MHD_TLS_CONN_NO_TLS = 0, /**< Not a TLS connection (plain socket). */
+ MHD_TLS_CONN_INIT, /**< TLS connection is not established yet. */
+ MHD_TLS_CONN_HANDSHAKING, /**< TLS is in handshake process. */
+ MHD_TLS_CONN_CONNECTED, /**< TLS is established. */
+ MHD_TLS_CONN_WR_CLOSING, /**< Closing WR side of TLS layer. */
+ MHD_TLS_CONN_WR_CLOSED, /**< WR side of TLS layer is closed. */
+ MHD_TLS_CONN_TLS_CLOSING, /**< TLS session is terminating. */
+ MHD_TLS_CONN_TLS_CLOSED, /**< TLS session is terminated. */
+ MHD_TLS_CONN_TLS_FAILED, /**< TLS session failed. */
+ MHD_TLS_CONN_INVALID_STATE/**< Sentinel. Not a valid value. */
+};
+
/**
* Should all state transitions be printed to stderr?
*/
@@ -541,6 +679,7 @@
#if DEBUG_STATES
const char *
MHD_state_to_string (enum MHD_CONNECTION_STATE state);
+
#endif
#endif
@@ -593,6 +732,7 @@
MHD_CONN_USE_KEEPALIVE = 1
};
+
/**
* State kept for each HTTP request.
*/
@@ -742,11 +882,13 @@
*/
struct sockaddr *addr;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
* Thread handle for this connection (if we are using
* one thread per connection).
*/
- MHD_thread_handle_ pid;
+ MHD_thread_handle_ID_ pid;
+#endif
/**
* Size of @e read_buffer (in bytes). This value indicates
@@ -797,13 +939,22 @@
*/
uint64_t response_write_position;
-#if LINUX
+ /**
+ * The copy of iov response.
+ * Valid if iovec response is used.
+ * Updated during send.
+ * Members are allocated in the pool.
+ */
+ struct MHD_iovec_track_ resp_iov;
+
+
+#if defined(_MHD_HAVE_SENDFILE)
enum MHD_resp_sender_
{
MHD_resp_sender_std = 0,
MHD_resp_sender_sendfile
} resp_sender;
-#endif /* LINUX */
+#endif /* _MHD_HAVE_SENDFILE */
/**
* Position in the 100 CONTINUE message that
@@ -848,11 +999,32 @@
MHD_socket socket_fd;
/**
+ * true if @e socket_fd is not TCP/IP (a UNIX domain socket, a pipe),
+ * false (TCP/IP) otherwise.
+ */
+ enum MHD_tristate is_nonip;
+
+ /**
* true if #socket_fd is non-blocking, false otherwise.
*/
bool sk_nonblck;
/**
+ * true if connection socket has set SIGPIPE suppression
+ */
+ bool sk_spipe_suppress;
+
+ /**
+ * Tracks TCP_CORK / TCP_NOPUSH of the connection socket.
+ */
+ enum MHD_tristate sk_corked;
+
+ /**
+ * Tracks TCP_NODELAY state of the connection socket.
+ */
+ enum MHD_tristate sk_nodelay;
+
+ /**
* Has this socket been closed for reading (i.e. other side closed
* the connection)? If so, we must completely close the connection
* once we are done sending our response (and stop trying to read
@@ -860,10 +1032,12 @@
*/
bool read_closed;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
* Set to `true` if the thread has been joined.
*/
bool thread_joined;
+#endif
/**
* Are we currently inside the "idle" handler (to avoid recursively
@@ -924,33 +1098,10 @@
uint64_t current_chunk_offset;
/**
- * Handler used for processing read connection operations
- * @sa #MHD_connection_handle_read, #MHD_tls_connection_handle_read
- */
- int (*read_handler) (struct MHD_Connection *connection);
-
- /**
- * Handler used for processing write connection operations
- * @sa #MHD_connection_handle_write, #MHD_tls_connection_handle_write
- */
- int (*write_handler) (struct MHD_Connection *connection);
-
- /**
- * Handler used for processing idle connection operations
- * @sa #MHD_connection_handle_idle, #MHD_tls_connection_handle_idle
- */
- int (*idle_handler) (struct MHD_Connection *connection);
-
- /**
* Function used for reading HTTP request stream.
*/
ReceiveCallback recv_cls;
- /**
- * Function used for writing HTTP response stream.
- */
- TransmitCallback send_cls;
-
#ifdef UPGRADE_SUPPORT
/**
* If this connection was upgraded, this points to
@@ -979,15 +1130,15 @@
int cipher;
/**
- * Could it be that we are ready to read due to TLS buffers
- * even though the socket is not?
+ * State of connection's TLS layer
*/
- bool tls_read_ready;
+ enum MHD_TLS_CONN_STATE tls_state;
/**
- * TLS layer was shut down?
+ * Could it be that we are ready to read due to TLS buffers
+ * even though the socket is not?
*/
- bool tls_closed;
+ bool tls_read_ready;
#endif /* HTTPS_SUPPORT */
/**
@@ -1003,7 +1154,7 @@
/**
* Is the connection wanting to resume?
*/
- bool resuming;
+ volatile bool resuming;
};
@@ -1044,7 +1195,7 @@
*
* Similarly, for writing to TLS, this epoll() will be on the
* connection's `socket_fd`, and this will merely be the FD which
- * the applicatio would write to. Hence this struct must always be
+ * the application would write to. Hence this struct must always be
* interpreted based on which field in `struct
* MHD_UpgradeResponseHandle` it is (`app` or `mhd`).
*/
@@ -1198,7 +1349,7 @@
* @remark This flag could be changed from thread that process
* connection's recv(), send() and response.
*/
- bool clean_ready;
+ volatile bool clean_ready;
};
#endif /* UPGRADE_SUPPORT */
@@ -1252,6 +1403,24 @@
void *default_handler_cls;
/**
+ * Daemon's flags (bitfield).
+ *
+ * @remark Keep this member after pointer value to keep it
+ * properly aligned as it will be used as member of union MHD_DaemonInfo.
+ */
+ enum MHD_FLAG options;
+
+ /**
+ * Head of doubly-linked list of new, externally added connections.
+ */
+ struct MHD_Connection *new_connections_head;
+
+ /**
+ * Tail of doubly-linked list of new, externally added connections.
+ */
+ struct MHD_Connection *new_connections_tail;
+
+ /**
* Head of doubly-linked list of our current, active connections.
*/
struct MHD_Connection *connections_head;
@@ -1281,6 +1450,11 @@
*/
struct MHD_Connection *cleanup_tail;
+ /**
+ * _MHD_YES if the @e listen_fd socket is a UNIX domain socket.
+ */
+ enum MHD_tristate listen_is_unix;
+
#ifdef EPOLL_SUPPORT
/**
* Head of EDLL of connections ready for processing (in epoll mode).
@@ -1292,7 +1466,35 @@
*/
struct MHD_Connection *eready_tail;
+ /**
+ * File descriptor associated with our epoll loop.
+ *
+ * @remark Keep this member after pointer value to keep it
+ * properly aligned as it will be used as member of union MHD_DaemonInfo.
+ */
+ int epoll_fd;
+
+ /**
+ * true if the @e listen_fd socket is in the 'epoll' set,
+ * false if not.
+ */
+ bool listen_socket_in_epoll;
+
#ifdef UPGRADE_SUPPORT
+#ifdef HTTPS_SUPPORT
+ /**
+ * File descriptor associated with the #run_epoll_for_upgrade() loop.
+ * Only available if #MHD_USE_HTTPS_EPOLL_UPGRADE is set.
+ */
+ int epoll_upgrade_fd;
+
+ /**
+ * true if @e epoll_upgrade_fd is in the 'epoll' set,
+ * false if not.
+ */
+ bool upgrade_fd_in_epoll;
+#endif /* HTTPS_SUPPORT */
+
/**
* Head of EDLL of upgraded connections ready for processing (in epoll mode).
*/
@@ -1400,12 +1602,20 @@
*/
void *unescape_callback_cls;
+ /**
+ * Listen port.
+ *
+ * @remark Keep this member after pointer value to keep it
+ * properly aligned as it will be used as member of union MHD_DaemonInfo.
+ */
+ uint16_t port;
+
#ifdef HAVE_MESSAGES
/**
* Function for logging error messages (if we
* support error reporting).
*/
- void (*custom_error_log) (void *cls, const char *fmt, va_list va);
+ MHD_LogCallback custom_error_log;
/**
* Closure argument to @e custom_error_log.
@@ -1419,9 +1629,19 @@
struct MHD_Daemon *master;
/**
+ * Listen socket.
+ *
+ * @remark Keep this member after pointer value to keep it
+ * properly aligned as it will be used as member of union MHD_DaemonInfo.
+ */
+ MHD_socket listen_fd;
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ /**
* Worker daemons (one per thread)
*/
struct MHD_Daemon *worker_pool;
+#endif
/**
* Table storing number of connections per IP
@@ -1429,6 +1649,14 @@
void *per_ip_connection_count;
/**
+ * Number of active parallel connections.
+ *
+ * @remark Keep this member after pointer value to keep it
+ * properly aligned as it will be used as member of union MHD_DaemonInfo.
+ */
+ unsigned int connections;
+
+ /**
* Size of the per-connection memory pools.
*/
size_t pool_size;
@@ -1438,6 +1666,7 @@
*/
size_t pool_increment;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
* Size of threads created by MHD.
*/
@@ -1451,7 +1680,7 @@
/**
* The select thread handle (if we have internal select)
*/
- MHD_thread_handle_ pid;
+ MHD_thread_handle_ID_ pid;
/**
* Mutex for per-IP connection counts.
@@ -1465,9 +1694,16 @@
MHD_mutex_ cleanup_connection_mutex;
/**
- * Listen socket.
+ * Mutex for any access to the "new connections" DL-list.
*/
- MHD_socket listen_fd;
+ MHD_mutex_ new_connections_mutex;
+#endif
+
+ /**
+ * Our #MHD_OPTION_SERVER_INSANITY level, bits indicating
+ * which sanity checks are off.
+ */
+ enum MHD_DisableSanityCheck insanity_level;
/**
* Whether to allow/disallow/ignore reuse of listening address.
@@ -1480,36 +1716,10 @@
*/
int listening_address_reuse;
-#ifdef EPOLL_SUPPORT
- /**
- * File descriptor associated with our epoll loop.
- */
- int epoll_fd;
-
- /**
- * true if the listen socket is in the 'epoll' set,
- * false if not.
- */
- bool listen_socket_in_epoll;
-
-#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- /**
- * File descriptor associated with the #run_epoll_for_upgrade() loop.
- * Only available if #MHD_USE_HTTPS_EPOLL_UPGRADE is set.
- */
- int epoll_upgrade_fd;
-
- /**
- * true if @e epoll_upgrade_fd is in the 'epoll' set,
- * false if not.
- */
- bool upgrade_fd_in_epoll;
-#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-
-#endif
/**
- * Inter-thread communication channel.
+ * Inter-thread communication channel (also used to unblock
+ * select() in non-threaded code).
*/
struct MHD_itc_ itc;
@@ -1519,7 +1729,7 @@
volatile bool shutdown;
/**
- * Has this deamon been quiesced via #MHD_quiesce_daemon()?
+ * Has this daemon been quiesced via #MHD_quiesce_daemon()?
* If so, we should no longer use the @e listen_fd (including
* removing it from the @e epoll_fd when possible).
*/
@@ -1537,7 +1747,13 @@
/*
* Do we need to process resuming connections?
*/
- bool resuming;
+ volatile bool resuming;
+
+ /**
+ * Indicate that new connections in @e new_connections_head list
+ * need to be processed.
+ */
+ volatile bool have_new;
/**
* 'True' if some data is already waiting to be processed.
@@ -1551,11 +1767,6 @@
bool data_already_pending;
/**
- * Number of active parallel connections.
- */
- unsigned int connections;
-
- /**
* Limit on the number of parallel connections.
*/
unsigned int connection_limit;
@@ -1573,19 +1784,14 @@
unsigned int per_ip_connection_limit;
/**
- * Daemon's flags (bitfield).
- */
- enum MHD_FLAG options;
-
- /**
- * Listen port.
+ * Be neutral (zero), strict (1) or permissive (-1) to client.
*/
- uint16_t port;
+ int strict_for_client;
/**
- * Be neutral (zero), strict (1) or permissive (-1) to client.
+ * True if SIGPIPE is blocked
*/
- int strict_for_client;
+ bool sigpipe_blocked;
#ifdef HTTPS_SUPPORT
#ifdef UPGRADE_SUPPORT
@@ -1625,12 +1831,35 @@
*/
gnutls_dh_params_t dh_params;
+ /**
+ * Server PSK credentials
+ */
+ gnutls_psk_server_credentials_t psk_cred;
+
#if GNUTLS_VERSION_MAJOR >= 3
/**
* Function that can be used to obtain the certificate. Needed
* for SNI support. See #MHD_OPTION_HTTPS_CERT_CALLBACK.
*/
gnutls_certificate_retrieve_function2 *cert_callback;
+
+ /**
+ * Function that can be used to obtain the shared key.
+ */
+ MHD_PskServerCredentialsCallback cred_callback;
+
+ /**
+ * Closure for @e cred_callback.
+ */
+ void *cred_callback_cls;
+#endif
+
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ /**
+ * Function that can be used to obtain the certificate. Needed
+ * for OCSP stapling support. See #MHD_OPTION_HTTPS_CERT_CALLBACK2.
+ */
+ gnutls_certificate_retrieve_function3 *cert_callback2;
#endif
/**
@@ -1663,7 +1892,12 @@
*/
bool have_dhparams;
-#endif /* HTTPS_SUPPORT */
+ /**
+ * true if ALPN is disabled.
+ */
+ bool disable_alpn;
+
+ #endif /* HTTPS_SUPPORT */
#ifdef DAUTH_SUPPORT
@@ -1677,10 +1911,12 @@
*/
struct MHD_NonceNc *nnc;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
/**
* A rw-lock for synchronizing access to @e nnc.
*/
MHD_mutex_ nnc_lock;
+#endif
/**
* Size of `digest_auth_random.
@@ -1705,14 +1941,16 @@
* The size of queue for listen socket.
*/
unsigned int listen_backlog_size;
-};
-
-#if EXTRA_CHECKS
-#define EXTRA_CHECK(a) do { if (!(a)) abort(); } while (0)
-#else
-#define EXTRA_CHECK(a)
-#endif
+ /**
+ * The number of user options used.
+ *
+ * Contains number of only meaningful options, i.e. #MHD_OPTION_END
+ * and #MHD_OPTION_ARRAY are not counted, while options inside
+ * #MHD_OPTION_ARRAY are counted.
+ */
+ size_t num_opts;
+};
/**
@@ -1724,15 +1962,16 @@
* @param element element to insert
*/
#define DLL_insert(head,tail,element) do { \
- EXTRA_CHECK (NULL == (element)->next); \
- EXTRA_CHECK (NULL == (element)->prev); \
- (element)->next = (head); \
- (element)->prev = NULL; \
- if ((tail) == NULL) \
- (tail) = element; \
- else \
- (head)->prev = element; \
- (head) = (element); } while (0)
+ mhd_assert (NULL == (element)->next); \
+ mhd_assert (NULL == (element)->prev); \
+ (element)->next = (head); \
+ (element)->prev = NULL; \
+ if ((tail) == NULL) { \
+ (tail) = element; \
+ } else { \
+ (head)->prev = element; \
+ } \
+ (head) = (element); } while (0)
/**
@@ -1745,19 +1984,20 @@
* @param element element to remove
*/
#define DLL_remove(head,tail,element) do { \
- EXTRA_CHECK ( (NULL != (element)->next) || ((element) == (tail))); \
- EXTRA_CHECK ( (NULL != (element)->prev) || ((element) == (head))); \
- if ((element)->prev == NULL) \
- (head) = (element)->next; \
- else \
- (element)->prev->next = (element)->next; \
- if ((element)->next == NULL) \
- (tail) = (element)->prev; \
- else \
- (element)->next->prev = (element)->prev; \
- (element)->next = NULL; \
- (element)->prev = NULL; } while (0)
-
+ mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \
+ mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \
+ if ((element)->prev == NULL) { \
+ (head) = (element)->next; \
+ } else { \
+ (element)->prev->next = (element)->next; \
+ } \
+ if ((element)->next == NULL) { \
+ (tail) = (element)->prev; \
+ } else { \
+ (element)->next->prev = (element)->prev; \
+ } \
+ (element)->next = NULL; \
+ (element)->prev = NULL; } while (0)
/**
@@ -1769,15 +2009,16 @@
* @param element element to insert
*/
#define XDLL_insert(head,tail,element) do { \
- EXTRA_CHECK (NULL == (element)->nextX); \
- EXTRA_CHECK (NULL == (element)->prevX); \
- (element)->nextX = (head); \
- (element)->prevX = NULL; \
- if (NULL == (tail)) \
- (tail) = element; \
- else \
- (head)->prevX = element; \
- (head) = (element); } while (0)
+ mhd_assert (NULL == (element)->nextX); \
+ mhd_assert (NULL == (element)->prevX); \
+ (element)->nextX = (head); \
+ (element)->prevX = NULL; \
+ if (NULL == (tail)) { \
+ (tail) = element; \
+ } else { \
+ (head)->prevX = element; \
+ } \
+ (head) = (element); } while (0)
/**
@@ -1790,18 +2031,20 @@
* @param element element to remove
*/
#define XDLL_remove(head,tail,element) do { \
- EXTRA_CHECK ( (NULL != (element)->nextX) || ((element) == (tail))); \
- EXTRA_CHECK ( (NULL != (element)->prevX) || ((element) == (head))); \
- if (NULL == (element)->prevX) \
- (head) = (element)->nextX; \
- else \
- (element)->prevX->nextX = (element)->nextX; \
- if (NULL == (element)->nextX) \
- (tail) = (element)->prevX; \
- else \
- (element)->nextX->prevX = (element)->prevX; \
- (element)->nextX = NULL; \
- (element)->prevX = NULL; } while (0)
+ mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \
+ mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \
+ if (NULL == (element)->prevX) { \
+ (head) = (element)->nextX; \
+ } else { \
+ (element)->prevX->nextX = (element)->nextX; \
+ } \
+ if (NULL == (element)->nextX) { \
+ (tail) = (element)->prevX; \
+ } else { \
+ (element)->nextX->prevX = (element)->prevX; \
+ } \
+ (element)->nextX = NULL; \
+ (element)->prevX = NULL; } while (0)
/**
@@ -1813,13 +2056,14 @@
* @param element element to insert
*/
#define EDLL_insert(head,tail,element) do { \
- (element)->nextE = (head); \
- (element)->prevE = NULL; \
- if ((tail) == NULL) \
- (tail) = element; \
- else \
- (head)->prevE = element; \
- (head) = (element); } while (0)
+ (element)->nextE = (head); \
+ (element)->prevE = NULL; \
+ if ((tail) == NULL) { \
+ (tail) = element; \
+ } else { \
+ (head)->prevE = element; \
+ } \
+ (head) = (element); } while (0)
/**
@@ -1831,17 +2075,19 @@
* @param tail pointer to the tail of the EDLL
* @param element element to remove
*/
-#define EDLL_remove(head,tail,element) do { \
- if ((element)->prevE == NULL) \
- (head) = (element)->nextE; \
- else \
- (element)->prevE->nextE = (element)->nextE; \
- if ((element)->nextE == NULL) \
- (tail) = (element)->prevE; \
- else \
- (element)->nextE->prevE = (element)->prevE; \
- (element)->nextE = NULL; \
- (element)->prevE = NULL; } while (0)
+#define EDLL_remove(head,tail,element) do { \
+ if ((element)->prevE == NULL) { \
+ (head) = (element)->nextE; \
+ } else { \
+ (element)->prevE->nextE = (element)->nextE; \
+ } \
+ if ((element)->nextE == NULL) { \
+ (tail) = (element)->prevE; \
+ } else { \
+ (element)->nextE->prevE = (element)->prevE; \
+ } \
+ (element)->nextE = NULL; \
+ (element)->prevE = NULL; } while (0)
/**
@@ -1859,16 +2105,20 @@
*
* @param connection context of the iteration
* @param key 0-terminated key string, never NULL
- * @param value 0-terminated value string, may be NULL
+ * @param key_size number of bytes in key
+ * @param value 0-terminated binary data, may include binary zeros, may be NULL
+ * @param value_size number of bytes in value
* @param kind origin of the key-value pair
* @return #MHD_YES on success (continue to iterate)
* #MHD_NO to signal failure (and abort iteration)
*/
-typedef int
+typedef enum MHD_Result
(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
- const char *key,
- const char *value,
- enum MHD_ValueKind kind);
+ const char *key,
+ size_t key_size,
+ const char *value,
+ size_t value_size,
+ enum MHD_ValueKind kind);
/**
@@ -1885,23 +2135,26 @@
* #MHD_YES for success (parsing succeeded, @a cb always
* returned #MHD_YES)
*/
-int
+enum MHD_Result
MHD_parse_arguments_ (struct MHD_Connection *connection,
- enum MHD_ValueKind kind,
- char *args,
- MHD_ArgumentIterator_ cb,
- unsigned int *num_headers);
+ enum MHD_ValueKind kind,
+ char *args,
+ MHD_ArgumentIterator_ cb,
+ unsigned int *num_headers);
/**
- * Check whether response header contains particular @a token.
+ * Check whether response header contains particular token.
*
* Token could be surrounded by spaces and tabs and delimited by comma.
* Case-insensitive match used for header names and tokens.
+ *
* @param response the response to query
* @param key header name
+ * @param key_len the length of @a key, not including optional
+ * terminating null-character.
* @param token the token to find
- * @param token_len the length of token, not including optional
+ * @param token_len the length of @a token, not including optional
* terminating null-character.
* @return true if token is found in specified header,
* false otherwise
@@ -1909,6 +2162,7 @@
bool
MHD_check_response_header_token_ci (const struct MHD_Response *response,
const char *key,
+ size_t key_len,
const char *token,
size_t token_len);
@@ -1924,10 +2178,12 @@
* false otherwise
*/
#define MHD_check_response_header_s_token_ci(r,k,tkn) \
- MHD_check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn))
+ MHD_check_response_header_token_ci ((r),(k),MHD_STATICSTR_LEN_ (k), \
+ (tkn),MHD_STATICSTR_LEN_ (tkn))
+
/**
- * Internal version of ::MHD_suspend_connection().
+ * Internal version of #MHD_suspend_connection().
*
* @remark In thread-per-connection mode: can be called from any thread,
* in any other mode: to be called only from thread that process
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/md5.c
^
|
@@ -10,48 +10,35 @@
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
+ * MD5Context structure, pass it to MHD_MD5Init, call MHD_MD5Update as
+ * needed on buffers full of bytes, and then call MHD_MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
-/* Based on OpenBSD modifications */
+/* Based on OpenBSD modifications.
+ * Optimized by Karlson2k (Evgeny Grin). */
#include "md5.h"
-#include "mhd_byteorder.h"
+#include <string.h>
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif /* HAVE_MEMORY_H */
+#include "mhd_bithelpers.h"
+#include "mhd_assert.h"
-#define PUT_64BIT_LE(cp, value) do { \
- (cp)[7] = (uint8_t)((value) >> 56); \
- (cp)[6] = (uint8_t)((value) >> 48); \
- (cp)[5] = (uint8_t)((value) >> 40); \
- (cp)[4] = (uint8_t)((value) >> 32); \
- (cp)[3] = (uint8_t)((value) >> 24); \
- (cp)[2] = (uint8_t)((value) >> 16); \
- (cp)[1] = (uint8_t)((value) >> 8); \
- (cp)[0] = (uint8_t)((value)); } while (0)
-
-#define PUT_32BIT_LE(cp, value) do { \
- (cp)[3] = (uint8_t)((value) >> 24); \
- (cp)[2] = (uint8_t)((value) >> 16); \
- (cp)[1] = (uint8_t)((value) >> 8); \
- (cp)[0] = (uint8_t)((value)); } while (0)
-
-static uint8_t PADDING[MD5_BLOCK_SIZE] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-/*
+/**
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
+ *
+ * @param ctx must be a `struct MD5Context *`
*/
void
-MD5Init(struct MD5Context *ctx)
+MHD_MD5Init (void *ctx_)
{
- if (!ctx)
- return;
+ struct MD5Context *ctx = ctx_;
+ mhd_assert (ctx != NULL);
ctx->count = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
@@ -59,126 +46,99 @@
ctx->state[3] = 0x10325476;
}
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
-{
- size_t have, need;
-
- if (!ctx || !input)
- return;
-
- /* Check how many bytes we already have and how many more we need. */
- have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
- need = MD5_BLOCK_SIZE - have;
- /* Update bitcount */
- ctx->count += (uint64_t)len << 3;
+static void
+MD5Transform (uint32_t state[4],
+ const uint8_t block[MD5_BLOCK_SIZE]);
- if (len >= need)
- {
- if (have != 0)
- {
- memcpy(ctx->buffer + have, input, need);
- MD5Transform(ctx->state, ctx->buffer);
- input += need;
- len -= need;
- have = 0;
- }
- /* Process data in MD5_BLOCK_SIZE-byte chunks. */
- while (len >= MD5_BLOCK_SIZE)
- {
- MD5Transform(ctx->state, input);
- input += MD5_BLOCK_SIZE;
- len -= MD5_BLOCK_SIZE;
- }
- }
-
- /* Handle any remaining bytes of data. */
- if (len != 0)
- memcpy(ctx->buffer + have, input, len);
-}
-
-/*
- * Pad pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
+/**
+ * Final wrapup, fill in digest and zero out ctx.
+ *
+ * @param ctx must be a `struct MD5Context *`
*/
void
-MD5Pad(struct MD5Context *ctx)
+MHD_MD5Final (void *ctx_,
+ uint8_t digest[MD5_DIGEST_SIZE])
{
- uint8_t count[8];
- size_t padlen;
+ struct MD5Context *ctx = ctx_;
+ uint64_t count_bits;
+ size_t have_bytes;
- if (!ctx)
- return;
+ mhd_assert (ctx != NULL);
+ mhd_assert (digest != NULL);
/* Convert count to 8 bytes in little endian order. */
- PUT_64BIT_LE(count, ctx->count);
-
- /* Pad out to 56 mod 64. */
- padlen = MD5_BLOCK_SIZE -
- ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
- if (padlen < 1 + 8)
- padlen += MD5_BLOCK_SIZE;
- MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
- MD5Update(ctx, count, 8);
-}
+ have_bytes = (ctx->count) & (MD5_BLOCK_SIZE - 1);
-/*
- * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
- */
-void
-MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
-{
- int i;
-
- if (!ctx || !digest)
- return;
+ /* Pad data */
+ /* Buffer always have space for one byte or more. */
+ ctx->buffer[have_bytes++] = 0x80; /* First padding byte is 0x80 */
+
+ if (MD5_BLOCK_SIZE - have_bytes < 8)
+ { /* Not enough space to put number of bits */
+ while (have_bytes < MD5_BLOCK_SIZE)
+ ctx->buffer[have_bytes++] = 0;
+ MD5Transform (ctx->state, ctx->buffer);
+ have_bytes = 0; /* Additional block */
+ }
+ /* Pad out to 56 */
+ memset (ctx->buffer + have_bytes, 0, MD5_BLOCK_SIZE - have_bytes - 8);
- MD5Pad(ctx);
- for (i = 0; i < 4; i++)
- PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+ /* Put number of bits */
+ count_bits = ctx->count << 3;
+ _MHD_PUT_64BIT_LE (ctx->buffer + 56, count_bits);
+ MD5Transform (ctx->state, ctx->buffer);
+
+ /* Put digest in LE mode */
+ _MHD_PUT_32BIT_LE (digest, ctx->state[0]);
+ _MHD_PUT_32BIT_LE (digest + 4, ctx->state[1]);
+ _MHD_PUT_32BIT_LE (digest + 8, ctx->state[2]);
+ _MHD_PUT_32BIT_LE (digest + 12, ctx->state[3]);
- memset(ctx, 0, sizeof(*ctx));
+ /* Erase buffer */
+ memset (ctx, 0, sizeof(*ctx));
}
+/**
+ * Number of bytes in single SHA-256 word
+ * used to process data
+ */
+#define MD5_BYTES_IN_WORD (32 / 8)
+
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
+#define F2(x, y, z) F1 (z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+ (w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x)
-/*
+/**
* The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
-void
-MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
+static void
+MD5Transform (uint32_t state[4],
+ const uint8_t block[MD5_BLOCK_SIZE])
{
- uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4];
+ uint32_t a, b, c, d;
#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
- memcpy(in, block, sizeof(in));
+ const uint32_t *in = (const uint32_t *) block;
#else
- for (a = 0; a < MD5_BLOCK_SIZE / 4; a++)
+ uint32_t in[MD5_BLOCK_SIZE / MD5_BYTES_IN_WORD];
+ int i;
+
+ for (i = 0; i < MD5_BLOCK_SIZE / MD5_BYTES_IN_WORD; i++)
{
- in[a] = (uint32_t)(
- (uint32_t)(block[a * 4 + 0]) |
- (uint32_t)(block[a * 4 + 1]) << 8 |
- (uint32_t)(block[a * 4 + 2]) << 16 |
- (uint32_t)(block[a * 4 + 3]) << 24);
+ in[i] = _MHD_GET_32BIT_LE (block + i * MD5_BYTES_IN_WORD);
}
#endif
@@ -187,73 +147,73 @@
c = state[2];
d = state[3];
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+ MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21);
state[0] += a;
state[1] += b;
@@ -261,4 +221,58 @@
state[3] += d;
}
+
+/**
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MHD_MD5Update (void *ctx_,
+ const uint8_t *input,
+ size_t len)
+{
+ struct MD5Context *ctx = ctx_;
+ size_t have, need;
+
+ mhd_assert (ctx != NULL);
+ mhd_assert ((ctx != NULL) || (len == 0));
+
+ /* Check how many bytes we already have and how many more we need. */
+ have = (size_t) ((ctx->count) & (MD5_BLOCK_SIZE - 1));
+ need = MD5_BLOCK_SIZE - have;
+
+ /* Update bytecount */
+ ctx->count += (uint64_t) len;
+
+ if (len >= need)
+ {
+ if (have != 0)
+ {
+ memcpy (ctx->buffer + have,
+ input,
+ need);
+ MD5Transform (ctx->state, ctx->buffer);
+ input += need;
+ len -= need;
+ have = 0;
+ }
+
+ /* Process data in MD5_BLOCK_SIZE-byte chunks. */
+ while (len >= MD5_BLOCK_SIZE)
+ {
+ MD5Transform (ctx->state,
+ (const unsigned char *) input);
+ input += MD5_BLOCK_SIZE;
+ len -= MD5_BLOCK_SIZE;
+ }
+ }
+
+ /* Handle any remaining bytes of data. */
+ if (0 != len)
+ memcpy (ctx->buffer + have,
+ input,
+ len);
+}
+
+
/* end of md5.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/md5.h
^
|
@@ -10,55 +10,60 @@
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
+ * MD5Context structure, pass it to MHD_MD5Init, call MHD_MD5Update as
+ * needed on buffers full of bytes, and then call MHD_MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
#ifndef MHD_MD5_H
#define MHD_MD5_H
-#include "platform.h"
-
-#define MD5_BLOCK_SIZE 64
-#define MD5_DIGEST_SIZE 16
-#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1)
+#include "mhd_options.h"
+#include <stdint.h>
+#include <stddef.h>
+
+#define MD5_BLOCK_SIZE 64
+#define MD5_DIGEST_SIZE 16
+#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1)
struct MD5Context
{
- uint32_t state[4]; /* state */
- uint64_t count; /* number of bits, mod 2^64 */
- uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */
+ uint32_t state[4]; /* state */
+ uint64_t count; /* number of bytes, mod 2^64 */
+ uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */
};
-/*
+
+/**
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
*/
-void MD5Init(struct MD5Context *ctx);
+void
+MHD_MD5Init (void *ctx_);
+
-/*
+/**
* Update context to reflect the concatenation of another buffer full
* of bytes.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
*/
-void MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len);
+void
+MHD_MD5Update (void *ctx_,
+ const uint8_t *input,
+ size_t len);
-/*
- * Pad pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void MD5Pad(struct MD5Context *ctx);
-/*
+/**
* Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
*/
-void MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx);
+void
+MHD_MD5Final (void *ctx_,
+ uint8_t digest[MD5_DIGEST_SIZE]);
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]);
#endif /* !MHD_MD5_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/memorypool.c
^
|
@@ -1,6 +1,7 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007--2019 Daniel Pittman, Christian Grothoff and
+ Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,15 +22,36 @@
* @file memorypool.c
* @brief memory pool
* @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
*/
#include "memorypool.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "mhd_assert.h"
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#ifdef HAVE_SYSCONF
+#include <unistd.h>
+#if defined(_SC_PAGE_SIZE)
+#define MHD_SC_PAGESIZE _SC_PAGE_SIZE
+#elif defined(_SC_PAGESIZE)
+#define MHD_SC_PAGESIZE _SC_PAGESIZE
+#endif /* _SC_PAGESIZE */
+#endif /* HAVE_SYSCONF */
/* define MAP_ANONYMOUS for Mac OS X */
-#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void*)-1)
+#if defined(_WIN32)
+#define MAP_FAILED NULL
+#elif ! defined(MAP_FAILED)
+#define MAP_FAILED ((void*) -1)
#endif
/**
@@ -40,7 +62,44 @@
/**
* Round up 'n' to a multiple of ALIGN_SIZE.
*/
-#define ROUND_TO_ALIGN(n) ((n+(ALIGN_SIZE-1)) & (~(ALIGN_SIZE-1)))
+#define ROUND_TO_ALIGN(n) (((n) + (ALIGN_SIZE - 1)) \
+ / (ALIGN_SIZE) *(ALIGN_SIZE))
+
+#if defined(PAGE_SIZE) && (0 < (PAGE_SIZE + 0))
+#define MHD_DEF_PAGE_SIZE_ PAGE_SIZE
+#elif defined(PAGESIZE) && (0 < (PAGESIZE + 0))
+#define MHD_DEF_PAGE_SIZE_ PAGESIZE
+#else /* ! PAGESIZE */
+#define MHD_DEF_PAGE_SIZE_ (4096)
+#endif /* ! PAGESIZE */
+
+/**
+ * Size of memory page
+ */
+static size_t MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_; /* Default fallback value */
+
+/**
+ * Initialise values for memory pools
+ */
+void
+MHD_init_mem_pools_ (void)
+{
+#ifdef MHD_SC_PAGESIZE
+ long result;
+ result = sysconf (MHD_SC_PAGESIZE);
+ if (-1 != result)
+ MHD_sys_page_size_ = (size_t) result;
+ else
+ MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_;
+#elif defined(_WIN32)
+ SYSTEM_INFO si;
+ GetSystemInfo (&si);
+ MHD_sys_page_size_ = (size_t) si.dwPageSize;
+#else
+ MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_;
+#endif /* _WIN32 */
+ mhd_assert (0 == (MHD_sys_page_size_ % ALIGN_SIZE));
+}
/**
@@ -53,7 +112,7 @@
/**
* Pointer to the pool's memory
*/
- char *memory;
+ uint8_t *memory;
/**
* Size of the pool.
@@ -66,14 +125,14 @@
size_t pos;
/**
- * Offset of the last unallocated byte.
+ * Offset of the byte after the last unallocated byte.
*/
size_t end;
/**
- * #MHD_NO if pool was malloc'ed, #MHD_YES if mmapped (VirtualAlloc'ed for W32).
+ * 'false' if pool was malloc'ed, 'true' if mmapped (VirtualAlloc'ed for W32).
*/
- int is_mmap;
+ bool is_mmap;
};
@@ -87,48 +146,63 @@
MHD_pool_create (size_t max)
{
struct MemoryPool *pool;
+ size_t alloc_size;
+ mhd_assert (max > 0);
+ alloc_size = 0;
pool = malloc (sizeof (struct MemoryPool));
if (NULL == pool)
return NULL;
#if defined(MAP_ANONYMOUS) || defined(_WIN32)
- if (max <= 32 * 1024)
+ if ( (max <= 32 * 1024) ||
+ (max < MHD_sys_page_size_ * 4 / 3) )
+ {
pool->memory = MAP_FAILED;
+ }
else
-#if defined(MAP_ANONYMOUS) && !defined(_WIN32)
+ {
+ /* Round up allocation to page granularity. */
+ alloc_size = max + MHD_sys_page_size_ - 1;
+ alloc_size -= alloc_size % MHD_sys_page_size_;
+#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
pool->memory = mmap (NULL,
- max,
+ alloc_size,
PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS,
+ MAP_PRIVATE | MAP_ANONYMOUS,
-1,
0);
#elif defined(_WIN32)
pool->memory = VirtualAlloc (NULL,
- max,
+ alloc_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
-#endif
-#else
+#endif /* _WIN32 */
+ }
+#else /* ! _WIN32 && ! MAP_ANONYMOUS */
pool->memory = MAP_FAILED;
-#endif
- if ( (MAP_FAILED == pool->memory) ||
- (NULL == pool->memory))
+#endif /* ! _WIN32 && ! MAP_ANONYMOUS */
+ if (MAP_FAILED == pool->memory)
+ {
+ alloc_size = ROUND_TO_ALIGN (max);
+ pool->memory = malloc (alloc_size);
+ if (NULL == pool->memory)
{
- pool->memory = malloc (max);
- if (NULL == pool->memory)
- {
- free (pool);
- return NULL;
- }
- pool->is_mmap = MHD_NO;
+ free (pool);
+ return NULL;
}
+ pool->is_mmap = false;
+ }
+#if defined(MAP_ANONYMOUS) || defined(_WIN32)
else
- {
- pool->is_mmap = MHD_YES;
- }
+ {
+ pool->is_mmap = true;
+ }
+#endif /* _WIN32 || MAP_ANONYMOUS */
+ mhd_assert (0 == (((uintptr_t) pool->memory) % ALIGN_SIZE));
pool->pos = 0;
- pool->end = max;
- pool->size = max;
+ pool->end = alloc_size;
+ pool->size = alloc_size;
+ mhd_assert (0 < alloc_size);
return pool;
}
@@ -143,10 +217,13 @@
{
if (NULL == pool)
return;
- if (MHD_NO == pool->is_mmap)
+
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
+ if (! pool->is_mmap)
free (pool->memory);
else
-#if defined(MAP_ANONYMOUS) && !defined(_WIN32)
+#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
munmap (pool->memory,
pool->size);
#elif defined(_WIN32)
@@ -169,6 +246,8 @@
size_t
MHD_pool_get_free (struct MemoryPool *pool)
{
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
return (pool->end - pool->pos);
}
@@ -178,7 +257,7 @@
*
* @param pool memory pool to use for the operation
* @param size number of bytes to allocate
- * @param from_end allocate from end of pool (set to #MHD_YES);
+ * @param from_end allocate from end of pool (set to 'true');
* use this for small, persistent allocations that
* will never be reallocated
* @return NULL if the pool cannot support size more
@@ -186,28 +265,30 @@
*/
void *
MHD_pool_allocate (struct MemoryPool *pool,
- size_t size,
- int from_end)
+ size_t size,
+ bool from_end)
{
void *ret;
size_t asize;
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
asize = ROUND_TO_ALIGN (size);
if ( (0 == asize) && (0 != size) )
return NULL; /* size too close to SIZE_MAX */
if ( (pool->pos + asize > pool->end) ||
(pool->pos + asize < pool->pos))
return NULL;
- if (from_end == MHD_YES)
- {
- ret = &pool->memory[pool->end - asize];
- pool->end -= asize;
- }
+ if (from_end)
+ {
+ ret = &pool->memory[pool->end - asize];
+ pool->end -= asize;
+ }
else
- {
- ret = &pool->memory[pool->pos];
- pool->pos += asize;
- }
+ {
+ ret = &pool->memory[pool->pos];
+ pool->pos += asize;
+ }
return ret;
}
@@ -219,7 +300,7 @@
* If the given block is not the most recently
* (re)allocated block, the memory of the previous
* allocation may be leaked until the pool is
- * destroyed (and copying the data maybe required).
+ * destroyed or reset.
*
* @param pool memory pool to use for the operation
* @param old the existing block
@@ -232,53 +313,65 @@
void *
MHD_pool_reallocate (struct MemoryPool *pool,
void *old,
- size_t old_size,
- size_t new_size)
+ size_t old_size,
+ size_t new_size)
{
- void *ret;
size_t asize;
+ uint8_t *new_blc;
- asize = ROUND_TO_ALIGN (new_size);
- if ( (0 == asize) &&
- (0 != new_size) )
- return NULL; /* new_size too close to SIZE_MAX */
- if ( (pool->end < old_size) ||
- (pool->end < asize) )
- return NULL; /* unsatisfiable or bogus request */
-
- if ( (pool->pos >= old_size) &&
- (&pool->memory[pool->pos - old_size] == old) )
- {
- /* was the previous allocation - optimize! */
- if (pool->pos + asize - old_size <= pool->end)
- {
- /* fits */
- pool->pos += asize - old_size;
- if (asize < old_size) /* shrinking - zero again! */
- memset (&pool->memory[pool->pos],
- 0,
- old_size - asize);
- return old;
- }
- /* does not fit */
- return NULL;
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
+ mhd_assert (old != NULL || old_size == 0);
+ mhd_assert (old == NULL || pool->memory <= (uint8_t*) old);
+ mhd_assert (old == NULL || pool->memory + pool->size >= (uint8_t*) old
+ + old_size);
+ /* Blocks "from the end" must not be reallocated */
+ mhd_assert (old == NULL || old_size == 0 || \
+ pool->memory + pool->pos > (uint8_t*) old);
+
+ if (0 != old_size)
+ { /* Need to save some data */
+ const size_t old_offset = (uint8_t*) old - pool->memory;
+ const bool shrinking = (old_size > new_size);
+ /* Try resizing in-place */
+ if (shrinking)
+ { /* Shrinking in-place, zero-out freed part */
+ memset ((uint8_t*) old + new_size, 0, old_size - new_size);
}
- if (asize <= old_size)
- return old; /* cannot shrink, no need to move */
- if ((pool->pos + asize >= pool->pos) &&
- (pool->pos + asize <= pool->end))
- {
- /* fits */
- ret = &pool->memory[pool->pos];
- if (0 != old_size)
- memmove (ret,
- old,
- old_size);
- pool->pos += asize;
- return ret;
+ if (pool->pos == ROUND_TO_ALIGN (old_offset + old_size))
+ { /* "old" block is the last allocated block */
+ const size_t new_apos = ROUND_TO_ALIGN (old_offset + new_size);
+ if (! shrinking)
+ { /* Grow in-place, check for enough space. */
+ if ( (new_apos > pool->end) ||
+ (new_apos < pool->pos) ) /* Value wrap */
+ return NULL; /* No space */
+ }
+ /* Resized in-place */
+ pool->pos = new_apos;
+ return old;
}
- /* does not fit */
- return NULL;
+ if (shrinking)
+ return old; /* Resized in-place, freed part remains allocated */
+ }
+ /* Need to allocate new block */
+ asize = ROUND_TO_ALIGN (new_size);
+ if ( ( (0 == asize) &&
+ (0 != new_size) ) || /* Value wrap, too large new_size. */
+ (asize > pool->end - pool->pos) ) /* Not enough space */
+ return NULL;
+
+ new_blc = pool->memory + pool->pos;
+ pool->pos += asize;
+
+ if (0 != old_size)
+ {
+ /* Move data to new block, old block remains allocated */
+ memcpy (new_blc, old, old_size);
+ /* Zero-out old block */
+ memset (old, 0, old_size);
+ }
+ return new_blc;
}
@@ -297,28 +390,63 @@
*/
void *
MHD_pool_reset (struct MemoryPool *pool,
- void *keep,
- size_t copy_bytes,
+ void *keep,
+ size_t copy_bytes,
size_t new_size)
{
+ mhd_assert (pool->end >= pool->pos);
+ mhd_assert (pool->size >= pool->end - pool->pos);
+ mhd_assert (copy_bytes < new_size);
+ mhd_assert (keep != NULL || copy_bytes == 0);
+ mhd_assert (keep == NULL || pool->memory <= (uint8_t*) keep);
+ mhd_assert (keep == NULL || pool->memory + pool->size >= (uint8_t*) keep
+ + copy_bytes);
if ( (NULL != keep) &&
(keep != pool->memory) )
- {
- if (0 != copy_bytes)
- memmove (pool->memory,
- keep,
- copy_bytes);
- keep = pool->memory;
- }
- pool->end = pool->size;
+ {
+ if (0 != copy_bytes)
+ memmove (pool->memory,
+ keep,
+ copy_bytes);
+ }
/* technically not needed, but safer to zero out */
if (pool->size > copy_bytes)
+ {
+ size_t to_zero; /** Size of area to zero-out */
+
+ to_zero = pool->size - copy_bytes;
+#ifdef _WIN32
+ if (pool->is_mmap)
+ {
+ size_t to_recommit; /** Size of decommitted and re-committed area. */
+ uint8_t *recommit_addr;
+ /* Round down to page size */
+ to_recommit = to_zero - to_zero % MHD_sys_page_size_;
+ recommit_addr = pool->memory + pool->size - to_recommit;
+
+ /* De-committing and re-committing again clear memory and make
+ * pages free / available for other needs until accessed. */
+ if (VirtualFree (recommit_addr,
+ to_recommit,
+ MEM_DECOMMIT))
+ {
+ to_zero -= to_recommit;
+
+ if (recommit_addr != VirtualAlloc (recommit_addr,
+ to_recommit,
+ MEM_COMMIT,
+ PAGE_READWRITE))
+ abort (); /* Serious error, must never happen */
+ }
+ }
+#endif /* _WIN32 */
memset (&pool->memory[copy_bytes],
0,
- pool->size - copy_bytes);
- if (NULL != keep)
- pool->pos = ROUND_TO_ALIGN (new_size);
- return keep;
+ to_zero);
+ }
+ pool->pos = ROUND_TO_ALIGN (new_size);
+ pool->end = pool->size;
+ return pool->memory;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/memorypool.h
^
|
@@ -1,6 +1,7 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007, 2009 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007--2019 Daniel Pittman, Christian Grothoff and
+ Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -23,12 +24,17 @@
* for each connection and bounding memory use for each
* request
* @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
*/
#ifndef MEMORYPOOL_H
#define MEMORYPOOL_H
-#include "internal.h"
+#include "mhd_options.h"
+#include <stddef.h>
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
/**
* Opaque handle for a memory pool.
@@ -37,6 +43,12 @@
*/
struct MemoryPool;
+/**
+ * Initialize values for memory pools
+ */
+void
+MHD_init_mem_pools_ (void);
+
/**
* Create a memory pool.
@@ -62,7 +74,7 @@
*
* @param pool memory pool to use for the operation
* @param size number of bytes to allocate
- * @param from_end allocate from end of pool (set to #MHD_YES);
+ * @param from_end allocate from end of pool (set to 'true');
* use this for small, persistent allocations that
* will never be reallocated
* @return NULL if the pool cannot support size more
@@ -70,8 +82,8 @@
*/
void *
MHD_pool_allocate (struct MemoryPool *pool,
- size_t size,
- int from_end);
+ size_t size,
+ bool from_end);
/**
@@ -81,21 +93,21 @@
* If the given block is not the most recently
* (re)allocated block, the memory of the previous
* allocation may be leaked until the pool is
- * destroyed (and copying the data maybe required).
+ * destroyed or reset.
*
* @param pool memory pool to use for the operation
* @param old the existing block
* @param old_size the size of the existing block
* @param new_size the new size of the block
* @return new address of the block, or
- * NULL if the pool cannot support new_size
- * bytes (old continues to be valid for old_size)
+ * NULL if the pool cannot support @a new_size
+ * bytes (old continues to be valid for @a old_size)
*/
void *
MHD_pool_reallocate (struct MemoryPool *pool,
- void *old,
- size_t old_size,
- size_t new_size);
+ void *old,
+ size_t old_size,
+ size_t new_size);
/**
@@ -123,8 +135,8 @@
*/
void *
MHD_pool_reset (struct MemoryPool *pool,
- void *keep,
- size_t copy_bytes,
+ void *keep,
+ size_t copy_bytes,
size_t new_size);
#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_assert.h
^
|
@@ -0,0 +1,49 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2017 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_assert.h
+ * @brief macros for mhd_assert()
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_ASSERT_H
+#define MHD_ASSERT_H 1
+
+#include "mhd_options.h"
+#ifdef NDEBUG
+# define mhd_assert(ignore) ((void) 0)
+#else /* _DEBUG */
+# ifdef HAVE_ASSERT
+# include <assert.h>
+# define mhd_assert(CHK) assert (CHK)
+# else /* ! HAVE_ASSERT */
+# include <stdio.h>
+# include <stdlib.h>
+# define mhd_assert(CHK) \
+ do { \
+ if (! (CHK)) { \
+ fprintf (stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \
+ __FILE__, (unsigned) __LINE__, #CHK); \
+ fflush (stderr); abort (); } \
+ } while (0)
+# endif /* ! HAVE_ASSERT */
+#endif /* _DEBUG */
+
+#endif /* ! MHD_ASSERT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_bithelpers.h
^
|
@@ -0,0 +1,239 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_bithelpers.h
+ * @brief macros for bits manipulations
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_BITHELPERS_H
+#define MHD_BITHELPERS_H 1
+
+#include "mhd_byteorder.h"
+#include <stdint.h>
+#if defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
+ defined(__OPTIMIZE__)))
+/* Declarations for VC & Clang/C2 built-ins */
+#include <intrin.h>
+#endif /* _MSC_FULL_VER */
+
+#ifndef __has_builtin
+/* Avoid precompiler errors with non-clang */
+# define __has_builtin(x) 0
+#endif
+
+
+#ifdef MHD_HAVE___BUILTIN_BSWAP32
+#define _MHD_BYTES_SWAP32(value32) \
+ ((uint32_t) __builtin_bswap32 ((uint32_t) value32))
+#elif defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
+ defined(__OPTIMIZE__)))
+/* Clang/C2 may not inline this function if optimizations are turned off. */
+#ifndef __clang__
+#pragma intrinsic(_byteswap_ulong)
+#endif /* ! __clang__ */
+#define _MHD_BYTES_SWAP32(value32) \
+ ((uint32_t) _byteswap_ulong ((uint32_t) value32))
+#elif __has_builtin (__builtin_bswap32)
+#define _MHD_BYTES_SWAP32(value32) \
+ ((uint32_t) __builtin_bswap32 ((uint32_t) value32))
+#else /* ! __has_builtin(__builtin_bswap32) */
+#define _MHD_BYTES_SWAP32(value32) \
+ ( (((uint32_t) (value32)) << 24) \
+ | ((((uint32_t) (value32)) & ((uint32_t) 0x0000FF00)) << 8) \
+ | ((((uint32_t) (value32)) & ((uint32_t) 0x00FF0000)) >> 8) \
+ | (((uint32_t) (value32)) >> 24) )
+#endif /* ! __has_builtin(__builtin_bswap32) */
+
+#ifdef MHD_HAVE___BUILTIN_BSWAP64
+#define _MHD_BYTES_SWAP64(value64) \
+ ((uint64_t) __builtin_bswap64 ((uint64_t) value64))
+#elif defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
+ defined(__OPTIMIZE__)))
+/* Clang/C2 may not inline this function if optimizations are turned off. */
+#ifndef __clang__
+#pragma intrinsic(_byteswap_uint64)
+#endif /* ! __clang__ */
+#define _MHD_BYTES_SWAP64(value64) \
+ ((uint64_t) _byteswap_uint64 ((uint64_t) value64))
+#elif __has_builtin (__builtin_bswap64)
+#define _MHD_BYTES_SWAP64(value64) \
+ ((uint64_t) __builtin_bswap64 ((uint64_t) value64))
+#else /* ! __has_builtin(__builtin_bswap64) */
+#define _MHD_BYTES_SWAP64(value64) \
+ ( (((uint64_t) (value64)) << 56) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x000000000000FF00)) << 40) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x0000000000FF0000)) << 24) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x00000000FF000000)) << 8) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x000000FF00000000)) >> 8) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x0000FF0000000000)) >> 24) \
+ | ((((uint64_t) (value64)) & ((uint64_t) 0x00FF000000000000)) >> 40) \
+ | (((uint64_t) (value64)) >> 56) )
+#endif /* ! __has_builtin(__builtin_bswap64) */
+
+
+/* _MHD_PUT_64BIT_LE (addr, value64)
+ * put native-endian 64-bit value64 to addr
+ * in little-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_64BIT_LE(addr, value64) \
+ ((*(uint64_t*) (addr)) = (uint64_t) (value64))
+#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_64BIT_LE(addr, value64) \
+ ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
+#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_64BIT_LE(addr, value64) do { \
+ ((uint8_t*) (addr))[0] = (uint8_t) ((uint64_t) (value64)); \
+ ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 8); \
+ ((uint8_t*) (addr))[2] = (uint8_t) (((uint64_t) (value64)) >> 16); \
+ ((uint8_t*) (addr))[3] = (uint8_t) (((uint64_t) (value64)) >> 24); \
+ ((uint8_t*) (addr))[4] = (uint8_t) (((uint64_t) (value64)) >> 32); \
+ ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 40); \
+ ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 48); \
+ ((uint8_t*) (addr))[7] = (uint8_t) (((uint64_t) (value64)) >> 56); \
+} while (0)
+#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+
+/* _MHD_PUT_32BIT_LE (addr, value32)
+ * put native-endian 32-bit value32 to addr
+ * in little-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_32BIT_LE(addr,value32) \
+ ((*(uint32_t*) (addr)) = (uint32_t) (value32))
+#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_32BIT_LE(addr, value32) \
+ ((*(uint32_t*) (addr)) = _MHD_BYTES_SWAP32 (value32))
+#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_32BIT_LE(addr, value32) do { \
+ ((uint8_t*) (addr))[0] = (uint8_t) ((uint32_t) (value32)); \
+ ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 8); \
+ ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 16); \
+ ((uint8_t*) (addr))[3] = (uint8_t) (((uint32_t) (value32)) >> 24); \
+} while (0)
+#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+
+/* _MHD_GET_32BIT_LE (addr)
+ * get little-endian 32-bit value storied at addr
+ * and return it in native-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_GET_32BIT_LE(addr) \
+ (*(const uint32_t*) (addr))
+#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_GET_32BIT_LE(addr) \
+ _MHD_BYTES_SWAP32 (*(const uint32_t*) (addr))
+#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_GET_32BIT_LE(addr) \
+ ( ( (uint32_t) (((const uint8_t*) addr)[0])) \
+ | (((uint32_t) (((const uint8_t*) addr)[1])) << 8) \
+ | (((uint32_t) (((const uint8_t*) addr)[2])) << 16) \
+ | (((uint32_t) (((const uint8_t*) addr)[3])) << 24) )
+#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
+
+
+/* _MHD_PUT_64BIT_BE (addr, value64)
+ * put native-endian 64-bit value64 to addr
+ * in big-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64) \
+ ((*(uint64_t*) (addr)) = (uint64_t) (value64))
+#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64) \
+ ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
+#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_64BIT_BE(addr, value64) do { \
+ ((uint8_t*) (addr))[7] = (uint8_t) ((uint64_t) (value64)); \
+ ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 8); \
+ ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 16); \
+ ((uint8_t*) (addr))[4] = (uint8_t) (((uint64_t) (value64)) >> 24); \
+ ((uint8_t*) (addr))[3] = (uint8_t) (((uint64_t) (value64)) >> 32); \
+ ((uint8_t*) (addr))[2] = (uint8_t) (((uint64_t) (value64)) >> 40); \
+ ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 48); \
+ ((uint8_t*) (addr))[0] = (uint8_t) (((uint64_t) (value64)) >> 56); \
+} while (0)
+#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+
+/* _MHD_PUT_32BIT_BE (addr, value32)
+ * put native-endian 32-bit value32 to addr
+ * in big-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_32BIT_BE(addr, value32) \
+ ((*(uint32_t*) (addr)) = (uint32_t) (value32))
+#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_32BIT_BE(addr, value32) \
+ ((*(uint32_t*) (addr)) = _MHD_BYTES_SWAP32 (value32))
+#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_32BIT_BE(addr, value32) do { \
+ ((uint8_t*) (addr))[3] = (uint8_t) ((uint32_t) (value32)); \
+ ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 8); \
+ ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 16); \
+ ((uint8_t*) (addr))[0] = (uint8_t) (((uint32_t) (value32)) >> 24); \
+} while (0)
+#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+
+/* _MHD_GET_32BIT_BE (addr)
+ * get big-endian 32-bit value storied at addr
+ * and return it in native-endian mode.
+ */
+#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_GET_32BIT_BE(addr) \
+ (*(const uint32_t*) (addr))
+#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_GET_32BIT_BE(addr) \
+ _MHD_BYTES_SWAP32 (*(const uint32_t*) (addr))
+#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_GET_32BIT_BE(addr) \
+ ( (((uint32_t) (((const uint8_t*) addr)[0])) << 24) \
+ | (((uint32_t) (((const uint8_t*) addr)[1])) << 16) \
+ | (((uint32_t) (((const uint8_t*) addr)[2])) << 8) \
+ | ((uint32_t) (((const uint8_t*) addr)[3])) )
+#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+
+
+/**
+ * Rotate right 32-bit value by number of bits.
+ * bits parameter must be more than zero and must be less than 32.
+ */
+#if defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
+ defined(__OPTIMIZE__)))
+/* Clang/C2 do not inline this function if optimizations are turned off. */
+#ifndef __clang__
+#pragma intrinsic(_rotr)
+#endif /* ! __clang__ */
+#define _MHD_ROTR32(value32, bits) \
+ ((uint32_t) _rotr ((uint32_t) (value32),(bits)))
+#else /* ! _MSC_FULL_VER */
+/* Defined in form which modern compiler could optimize. */
+#define _MHD_ROTR32(value32, bits) \
+ (((uint32_t) (value32)) >> (bits) | ((uint32_t) (value32)) << (32 - bits))
+#endif /* ! _MSC_FULL_VER */
+
+
+#endif /* ! MHD_BITHELPERS_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_byteorder.h
^
|
@@ -26,7 +26,9 @@
#ifndef MHD_BYTEORDER_H
#define MHD_BYTEORDER_H
-#include "platform.h"
+#include "mhd_options.h"
+
+#include <stdint.h>
#if HAVE_ENDIAN_H
#include <endian.h>
@@ -71,7 +73,8 @@
#if defined(__BYTE_ORDER__)
#if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
-#elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == \
+ __ORDER_LITTLE_ENDIAN__
#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
#elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
@@ -106,36 +109,40 @@
/* Byte order specification didn't detected in system headers */
/* Try some guessing */
-#if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
- (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN))
+#if (defined(__BIG_ENDIAN__) && ! defined(__LITTLE_ENDIAN__)) || \
+ (defined(_BIG_ENDIAN) && ! defined(_LITTLE_ENDIAN))
/* Seems that we are on big endian platform */
#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
-#elif (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
- (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN))
+#elif (defined(__LITTLE_ENDIAN__) && ! defined(__BIG_ENDIAN__)) || \
+ (defined(_LITTLE_ENDIAN) && ! defined(_BIG_ENDIAN))
/* Seems that we are on little endian platform */
#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
-#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
- defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \
- defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \
- defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__)
+#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
+ defined(__x86_64) || \
+ defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \
+ defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+ defined(__i686__) || \
+ defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__)
/* x86 family is little endian */
#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
-#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
- defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
+#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
+ defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
/* Looks like we are on ARM/MIPS in big endian mode */
#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
#elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
- defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
+ defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
/* Looks like we are on ARM/MIPS in little endian mode */
#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
-#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || defined(__hppa) || \
- defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \
- defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
+#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || \
+ defined(__hppa) || \
+ defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \
+ defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
/* Looks like we are on big endian platform */
#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
-#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(__ia64) || \
- defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \
- defined(__BFIN__) || defined(bfin) || defined(BFIN)
+#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \
+ defined(__ia64) || \
+ defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \
+ defined(__BFIN__) || defined(bfin) || defined(BFIN)
/* Looks like we are on little endian platform */
#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
#elif defined(_WIN32)
@@ -151,9 +158,11 @@
#ifdef _MHD_BYTE_ORDER
/* Some safety checks */
#if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN
-#error Configure detected big endian byte order but headers specify different byte order
-#elif !defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
-#error Configure did not detect big endian byte order but headers specify big endian byte order
+#error \
+ Configure detected big endian byte order but headers specify different byte order
+#elif ! defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#error \
+ Configure did not detect big endian byte order but headers specify big endian byte order
#endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
#endif /* _MHD_BYTE_ORDER */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_compat.c
^
|
@@ -25,7 +25,7 @@
*/
#include "mhd_compat.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#include <stdint.h>
#include <time.h>
#ifndef HAVE_SNPRINTF
@@ -38,7 +38,7 @@
#include <string.h> /* for memset() */
#endif /* ! HAVE_CALLOC */
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#ifndef HAVE_SNPRINTF
/* Emulate snprintf function on W32 */
@@ -61,16 +61,16 @@
format,
args);
va_end (args);
- if ((int)n == ret)
+ if ((int) n == ret)
s[n - 1] = 0;
if (ret >= 0)
return ret;
}
- va_start(args,
- format);
+ va_start (args,
+ format);
ret = _vscprintf (format,
args);
- va_end(args);
+ va_end (args);
if ( (0 <= ret) &&
(0 != n) &&
(NULL == s) )
@@ -79,36 +79,40 @@
return ret;
}
+
#endif /* HAVE_SNPRINTF */
#endif /* _WIN32 && !__CYGWIN__ */
#ifndef HAVE_CALLOC
#ifdef __has_builtin
-# if __has_builtin(__builtin_mul_overflow)
+# if __has_builtin (__builtin_mul_overflow)
# define MHD_HAVE_NUL_OVERFLOW 1
# endif
-#elif __GNUC__+0 >= 5
+#elif __GNUC__ + 0 >= 5
# define MHD_HAVE_NUL_OVERFLOW 1
#endif /* __GNUC__ >= 5 */
-void *MHD_calloc_(size_t nelem, size_t elsize)
+void *
+MHD_calloc_ (size_t nelem, size_t elsize)
{
size_t alloc_size;
void *ptr;
#ifdef MHD_HAVE_NUL_OVERFLOW
- if (__builtin_mul_overflow(nelem, elsize, &alloc_size) || 0 == alloc_size)
+ if (__builtin_mul_overflow (nelem, elsize, &alloc_size) || (0 == alloc_size))
return NULL;
#else /* ! MHD_HAVE_NUL_OVERFLOW */
alloc_size = nelem * elsize;
- if (0 == alloc_size || elsize != alloc_size / nelem)
+ if ((0 == alloc_size) || (elsize != alloc_size / nelem))
return NULL;
#endif /* ! MHD_HAVE_NUL_OVERFLOW */
ptr = malloc (alloc_size);
if (NULL == ptr)
return NULL;
- memset(ptr, 0, alloc_size);
+ memset (ptr, 0, alloc_size);
return ptr;
}
+
+
#endif /* ! HAVE_CALLOC */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_compat.h
^
|
@@ -40,20 +40,23 @@
#include <string.h>
#endif /* HAVE_STRING_H */
- /* MHD_strerror_ is strerror */
-#define MHD_strerror_(errnum) strerror((errnum))
+/* MHD_strerror_ is strerror */
+#define MHD_strerror_(errnum) strerror ((errnum))
/* Platform-independent snprintf name */
#if defined(HAVE_SNPRINTF)
#define MHD_snprintf_ snprintf
#else /* ! HAVE_SNPRINTF */
-#if defined(_WIN32)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
/* Emulate snprintf function on W32 */
-int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...);
+int W32_snprintf (char *__restrict s, size_t n, const char *__restrict format,
+ ...);
+
#define MHD_snprintf_ W32_snprintf
-#else /* ! _WIN32*/
-#error Your platform does not support snprintf() and MHD does not know how to emulate it on your platform.
-#endif /* ! _WIN32*/
+#else /* ! _WIN32 || __CYGWIN__ */
+#error \
+ Your platform does not support snprintf() and MHD does not know how to emulate it on your platform.
+#endif /* ! _WIN32 || __CYGWIN__ */
#endif /* ! HAVE_SNPRINTF */
#ifdef HAVE_RANDOM
@@ -61,14 +64,14 @@
* Generate pseudo random number at least 30-bit wide.
* @return pseudo random number at least 30-bit wide.
*/
-#define MHD_random_() random()
+#define MHD_random_() random ()
#else /* HAVE_RANDOM */
#ifdef HAVE_RAND
/**
* Generate pseudo random number at least 30-bit wide.
* @return pseudo random number at least 30-bit wide.
*/
-#define MHD_random_() ( (((long)rand()) << 15) + (long)rand() )
+#define MHD_random_() ( (((long) rand ()) << 15) + (long) rand () )
#endif /* HAVE_RAND */
#endif /* HAVE_RANDOM */
@@ -76,12 +79,13 @@
/**
* MHD_calloc_ is platform-independent calloc()
*/
-#define MHD_calloc_(n,s) calloc((n),(s))
+#define MHD_calloc_(n,s) calloc ((n),(s))
#else /* ! HAVE_CALLOC */
/**
* MHD_calloc_ is platform-independent calloc()
*/
-void *MHD_calloc_(size_t nelem, size_t elsize);
+void *MHD_calloc_ (size_t nelem, size_t elsize);
+
#endif /* ! HAVE_CALLOC */
#endif /* MHD_COMPAT_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_itc.c
^
|
@@ -34,7 +34,7 @@
#if defined(_MHD_ITC_PIPE)
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#if ! defined(_WIN32) || defined(__CYGWIN__)
#ifndef HAVE_PIPE2_FUNC
/**
@@ -48,7 +48,7 @@
{
unsigned int i;
- for (i=0;i<2;i++)
+ for (i = 0; i<2; i++)
{
int flags;
@@ -63,8 +63,10 @@
flags | O_NONBLOCK)) )
return 0;
}
- return !0;
+ return ! 0;
}
+
+
#endif /* ! HAVE_PIPE2_FUNC */
#endif /* !_WIN32 || __CYGWIN__ */
#endif /* _MHD_ITC_EVENTFD || _MHD_ITC_PIPE */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_itc.h
^
|
@@ -41,8 +41,9 @@
# include <stdlib.h>
/* Simple implementation of MHD_PANIC, to be used outside lib */
# define MHD_PANIC(msg) do { fprintf (stderr, \
- "Abnormal termination at %d line in file %s: %s\n", \
- (int)__LINE__, __FILE__, msg); abort();} while(0)
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
#endif /* ! MHD_PANIC */
#if defined(_MHD_ITC_EVENTFD)
@@ -63,12 +64,13 @@
* @param itc the itc to initialise
* @return non-zero if succeeded, zero otherwise
*/
-#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK)))
+#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
+ | EFD_NONBLOCK)))
/**
* Get description string of last errno for itc operations.
*/
-#define MHD_itc_last_strerror_() strerror(errno)
+#define MHD_itc_last_strerror_() strerror (errno)
/**
* Internal static const helper for MHD_itc_activate_()
@@ -82,7 +84,8 @@
* @return non-zero if succeeded, zero otherwise
*/
#define MHD_itc_activate_(itc, str) \
- ((write((itc).fd, (const void*)&_MHD_itc_wr_data, 8) > 0) || (EAGAIN == errno))
+ ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
+ errno))
/**
* Return read FD of @a itc which can be used for poll(), select() etc.
@@ -104,15 +107,17 @@
*/
#define MHD_itc_clear_(itc) \
do { uint64_t __b; int __r; \
- __r = read((itc).fd, &__b, sizeof(__b)); \
- (void)__r; } while(0)
+ __r = read ((itc).fd, &__b, sizeof(__b)); \
+ (void) __r; } while (0)
/**
- * Destroy previously initialised ITC
+ * Destroy previously initialised ITC. Note that close()
+ * on some platforms returns odd errors, so we ONLY fail
+ * if the errno is EBADF.
* @param itc the itc to destroy
* @return non-zero if succeeded, zero otherwise
*/
-#define MHD_itc_destroy_(itc) ((0 != close ((itc).fd)) || (EBADF != errno))
+#define MHD_itc_destroy_(itc) ((0 == close ((itc).fd)) || (EBADF != errno))
/**
* Check whether ITC has valid value.
@@ -153,20 +158,20 @@
* @return non-zero if succeeded, zero otherwise
*/
#ifdef HAVE_PIPE2_FUNC
-# define MHD_itc_init_(itc) (!pipe2((itc).fd, O_CLOEXEC | O_NONBLOCK))
+# define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
#else /* ! HAVE_PIPE2_FUNC */
# define MHD_itc_init_(itc) \
- ( (!pipe((itc).fd)) ? \
- (MHD_itc_nonblocking_((itc)) ? \
- (!0) : \
- (MHD_itc_destroy_((itc)), 0) ) \
- : (0) )
+ ( (! pipe ((itc).fd)) ? \
+ (MHD_itc_nonblocking_ ((itc)) ? \
+ (! 0) : \
+ (MHD_itc_destroy_ ((itc)), 0) ) \
+ : (0) )
#endif /* ! HAVE_PIPE2_FUNC */
/**
* Get description string of last errno for itc operations.
*/
-#define MHD_itc_last_strerror_() strerror(errno)
+#define MHD_itc_last_strerror_() strerror (errno)
/**
* Activate signal on @a itc
@@ -175,7 +180,7 @@
* @return non-zero if succeeded, zero otherwise
*/
#define MHD_itc_activate_(itc, str) \
- ((write((itc).fd[1], (const void*)(str), 1) > 0) || (EAGAIN == errno))
+ ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
/**
@@ -198,8 +203,8 @@
*/
#define MHD_itc_clear_(itc) do \
{ long __b; \
- while(0 < read((itc).fd[0], &__b, sizeof(__b))) \
- {} } while(0)
+ while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
+ {} } while (0)
/**
* Destroy previously initialised ITC
@@ -208,8 +213,8 @@
*/
#define MHD_itc_destroy_(itc) \
( (0 == close ((itc).fd[0])) ? \
- (0 == close ((itc).fd[1])) : \
- ((close ((itc).fd[1])), 0) )
+ (0 == close ((itc).fd[1])) : \
+ ((close ((itc).fd[1])), 0) )
/**
* Check whether ITC has valid value.
@@ -229,14 +234,15 @@
#define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
#ifndef HAVE_PIPE2_FUNC
- /**
- * Change itc FD options to be non-blocking.
- *
- * @param fd the FD to manipulate
- * @return non-zero if succeeded, zero otherwise
- */
- int
- MHD_itc_nonblocking_ (struct MHD_itc_ itc);
+/**
+ * Change itc FD options to be non-blocking.
+ *
+ * @param fd the FD to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+int
+MHD_itc_nonblocking_ (struct MHD_itc_ itc);
+
#endif /* ! HAVE_PIPE2_FUNC */
@@ -253,20 +259,20 @@
* @return non-zero if succeeded, zero otherwise
*/
#ifdef MHD_socket_pair_nblk_
-# define MHD_itc_init_(itc) MHD_socket_pair_nblk_((itc).sk)
+# define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
#else /* ! MHD_socket_pair_nblk_ */
# define MHD_itc_init_(itc) \
- (MHD_socket_pair_((itc).sk) ? \
- (MHD_itc_nonblocking_((itc)) ? \
- (!0) : \
- (MHD_itc_destroy_((itc)), 0) ) \
- : (0))
+ (MHD_socket_pair_ ((itc).sk) ? \
+ (MHD_itc_nonblocking_ ((itc)) ? \
+ (! 0) : \
+ (MHD_itc_destroy_ ((itc)), 0) ) \
+ : (0))
#endif /* ! MHD_socket_pair_nblk_ */
/**
* Get description string of last error for itc operations.
*/
-#define MHD_itc_last_strerror_() MHD_socket_last_strerr_()
+#define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
/**
* Activate signal on @a itc
@@ -275,8 +281,8 @@
* @return non-zero if succeeded, zero otherwise
*/
#define MHD_itc_activate_(itc, str) \
- ((MHD_send_((itc).sk[1], (str), 1) > 0) || \
- (MHD_SCKT_ERR_IS_EAGAIN_(MHD_socket_get_error_())))
+ ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
+ (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
/**
* Return read FD of @a itc which can be used for poll(), select() etc.
@@ -298,10 +304,10 @@
*/
#define MHD_itc_clear_(itc) do \
{ long __b; \
- while(0 < recv((itc).sk[0], \
- (char*)&__b, \
- sizeof(__b), 0)) \
- {} } while(0)
+ while (0 < recv ((itc).sk[0], \
+ (char*) &__b, \
+ sizeof(__b), 0)) \
+ {} } while (0)
/**
* Destroy previously initialised ITC
@@ -309,9 +315,9 @@
* @return non-zero if succeeded, zero otherwise
*/
#define MHD_itc_destroy_(itc) \
- ( MHD_socket_close_((itc).sk[0]) ? \
- MHD_socket_close_((itc).sk[1]) : \
- ((void)MHD_socket_close_((itc).sk[1]), 0) )
+ (MHD_socket_close_ ((itc).sk[0]) ? \
+ MHD_socket_close_ ((itc).sk[1]) : \
+ ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
/**
@@ -329,10 +335,12 @@
* Set @a itc to invalid value.
* @param itc the itc to set
*/
-#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET)
+#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
+ MHD_INVALID_SOCKET)
#ifndef MHD_socket_pair_nblk_
-# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_((pip).sk[0]) && MHD_socket_nonblocking_((pip).sk[1]))
+# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
+ MHD_socket_nonblocking_ ((pip).sk[1]))
#endif /* ! MHD_socket_pair_nblk_ */
#endif /* _MHD_ITC_SOCKETPAIR */
@@ -343,9 +351,9 @@
* @param itc the itc to destroy
*/
#define MHD_itc_destroy_chk_(itc) do { \
- if (!MHD_itc_destroy_(itc)) \
- MHD_PANIC(_("Failed to destroy ITC.\n")); \
- } while(0)
+ if (! MHD_itc_destroy_ (itc)) \
+ MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
+} while (0)
/**
* Check whether ITC has invalid value.
@@ -356,6 +364,6 @@
* @return boolean true if @a itc has invalid value,
* boolean false otherwise.
*/
-#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_(itc))
+#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
#endif /* MHD_ITC_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_itc_types.h
^
|
@@ -32,7 +32,7 @@
#include "mhd_options.h"
/* Force socketpair on native W32 */
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(_MHD_ITC_SOCKETPAIR)
+#if defined(_WIN32) && ! defined(__CYGWIN__) && ! defined(_MHD_ITC_SOCKETPAIR)
#error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform
#endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */
@@ -47,6 +47,12 @@
int fd;
};
+/**
+ * Static initialiser for struct MHD_itc_
+ */
+#define MHD_ITC_STATIC_INIT_INVALID { -1 }
+
+
#elif defined(_MHD_ITC_PIPE)
/* **************** Standard UNIX ITC implementation by pipe ********** */
@@ -58,6 +64,11 @@
int fd[2];
};
+/**
+ * Static initialiser for struct MHD_itc_
+ */
+#define MHD_ITC_STATIC_INIT_INVALID { { -1, -1 } }
+
#elif defined(_MHD_ITC_SOCKETPAIR)
/* **************** ITC implementation by socket pair ********** */
@@ -72,6 +83,12 @@
MHD_socket sk[2];
};
+/**
+ * Static initialiser for struct MHD_itc_
+ */
+#define MHD_ITC_STATIC_INIT_INVALID \
+ { { MHD_INVALID_SOCKET, MHD_INVALID_SOCKET } }
+
#endif /* _MHD_ITC_SOCKETPAIR */
#endif /* ! MHD_ITC_TYPES_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_limits.h
^
|
@@ -32,11 +32,17 @@
#include <limits.h>
#endif /* HAVE_LIMITS_H */
+#define MHD_UNSIGNED_TYPE_MAX_(type) ((type) - 1)
+/* Assume 8 bits per byte, no padding bits. */
+#define MHD_SIGNED_TYPE_MAX_(type) \
+ ( (type) ((( ((type) 1) << (sizeof(type) * 8 - 2)) - 1) * 2 + 1) )
+#define MHD_TYPE_IS_SIGNED_(type) (((type) 0)>((type) - 1))
+
#ifndef UINT_MAX
#ifdef __UINT_MAX__
#define UINT_MAX __UINT_MAX__
#else /* ! __UINT_MAX__ */
-#define UINT_MAX ((unsigned int) ~((unsigned int)0))
+#define UINT_MAX MHD_UNSIGNED_TYPE_MAX_ (unsigned int)
#endif /* ! __UINT_MAX__ */
#endif /* !UINT_MAX */
@@ -44,19 +50,19 @@
#ifdef __LONG_MAX__
#define LONG_MAX __LONG_MAX__
#else /* ! __LONG_MAX__ */
-#define LONG_MAX ((long) ~(((uint64_t) 1) << (8 * sizeof(long) - 1)))
+#define LONG_MAX MHD_SIGNED_TYPE_MAX (long)
#endif /* ! __LONG_MAX__ */
#endif /* !OFF_T_MAX */
#ifndef ULLONG_MAX
-#define ULLONG_MAX ((MHD_UNSIGNED_LONG_LONG) ~((MHD_UNSIGNED_LONG_LONG)0))
+#define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_ (MHD_UNSIGNED_LONG_LONG)
#endif /* !ULLONG_MAX */
#ifndef INT32_MAX
#ifdef __INT32_MAX__
#define INT32_MAX __INT32_MAX__
#else /* ! __INT32_MAX__ */
-#define INT32_MAX ((int32_t)0x7FFFFFFF)
+#define INT32_MAX ((int32_t) 0x7FFFFFFF)
#endif /* ! __INT32_MAX__ */
#endif /* !INT32_MAX */
@@ -64,38 +70,69 @@
#ifdef __UINT32_MAX__
#define UINT32_MAX __UINT32_MAX__
#else /* ! __UINT32_MAX__ */
-#define UINT32_MAX ((int32_t)0xFFFFFFFF)
+#define UINT32_MAX ((int32_t) 0xFFFFFFFF)
#endif /* ! __UINT32_MAX__ */
-#endif /* !UNT32_MAX */
+#endif /* !UINT32_MAX */
#ifndef UINT64_MAX
#ifdef __UINT64_MAX__
#define UINT64_MAX __UINT64_MAX__
#else /* ! __UINT64_MAX__ */
-#define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFF)
+#define UINT64_MAX ((uint64_t) 0xFFFFFFFFFFFFFFFF)
#endif /* ! __UINT64_MAX__ */
-#endif /* !INT32_MAX */
+#endif /* !UINT64_MAX */
+
+#ifndef INT64_MAX
+#ifdef __INT64_MAX__
+#define INT64_MAX __INT64_MAX__
+#else /* ! __INT64_MAX__ */
+#define INT64_MAX ((int64_t) 0x7FFFFFFFFFFFFFFF)
+#endif /* ! __UINT64_MAX__ */
+#endif /* !INT64_MAX */
#ifndef SIZE_MAX
#ifdef __SIZE_MAX__
#define SIZE_MAX __SIZE_MAX__
+#elif defined(UINTPTR_MAX)
+#define SIZE_MAX UINTPTR_MAX
#else /* ! __SIZE_MAX__ */
-#define SIZE_MAX ((size_t) ~((size_t)0))
-#endif /* ! __SIZE_MAX__ */
+#define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_ (size_t)
+#endif /* ! __SIZE_MAX__ */
#endif /* !SIZE_MAX */
+#ifndef SSIZE_MAX
+#ifdef __SSIZE_MAX__
+#define SSIZE_MAX __SSIZE_MAX__
+#elif defined(PTRDIFF_MAX)
+#define SSIZE_MAX PTRDIFF_MAX
+#elif defined(INTPTR_MAX)
+#define SSIZE_MAX INTPTR_MAX
+#else
+#define SSIZE_MAX MHD_SIGNED_TYPE_MAX_ (ssize_t)
+#endif
+#endif /* ! SSIZE_MAX */
+
#ifndef OFF_T_MAX
-#define OFF_T_MAX ((off_t) ~(((uint64_t) 1) << (8 * sizeof(off_t) - 1)))
+#ifdef OFF_MAX
+#define OFF_T_MAX OFF_MAX
+#elif defined(OFFT_MAX)
+#define OFF_T_MAX OFFT_MAX
+#elif defined(__APPLE__) && defined(__MACH__)
+#define OFF_T_MAX INT64_MAX
+#else
+#define OFF_T_MAX MHD_SIGNED_TYPE_MAX_ (off_t)
+#endif
#endif /* !OFF_T_MAX */
-#if defined(_LARGEFILE64_SOURCE) && !defined(OFF64_T_MAX)
-#define OFF64_T_MAX ((off64_t) ~(((uint64_t) 1) << (8 * sizeof(off64_t) - 1)))
+#if defined(_LARGEFILE64_SOURCE) && ! defined(OFF64_T_MAX)
+#define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_ (uint64_t)
#endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */
#ifndef TIME_T_MAX
-/* Assume that time_t is signed type. */
-/* Even if time_t is unsigned, TIME_T_MAX will be safe limit */
-#define TIME_T_MAX ( (time_t) ~(((uint64_t) 1) << (8 * sizeof(time_t) - 1)) )
+#define TIME_T_MAX ((time_t) \
+ (MHD_TYPE_IS_SIGNED_ (time_t) ? \
+ MHD_SIGNED_TYPE_MAX_ (time_t) : \
+ MHD_UNSIGNED_TYPE_MAX_ (time_t)))
#endif /* !TIME_T_MAX */
#ifndef TIMEVAL_TV_SEC_MAX
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_locks.h
^
|
@@ -39,6 +39,8 @@
#include "mhd_options.h"
+#ifdef MHD_USE_THREADS
+
#if defined(MHD_USE_W32_THREADS)
# define MHD_W32_MUTEX_ 1
# ifndef WIN32_LEAN_AND_MEAN
@@ -59,14 +61,15 @@
# include <stdlib.h>
/* Simple implementation of MHD_PANIC, to be used outside lib */
# define MHD_PANIC(msg) do { fprintf (stderr, \
- "Abnormal termination at %d line in file %s: %s\n", \
- (int)__LINE__, __FILE__, msg); abort();} while(0)
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
#endif /* ! MHD_PANIC */
#if defined(MHD_PTHREAD_MUTEX_)
- typedef pthread_mutex_t MHD_mutex_;
+typedef pthread_mutex_t MHD_mutex_;
#elif defined(MHD_W32_MUTEX_)
- typedef CRITICAL_SECTION MHD_mutex_;
+typedef CRITICAL_SECTION MHD_mutex_;
#endif
#if defined(MHD_PTHREAD_MUTEX_)
@@ -75,14 +78,25 @@
* @param pmutex pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-#define MHD_mutex_init_(pmutex) (!(pthread_mutex_init((pmutex), NULL)))
+#define MHD_mutex_init_(pmutex) (! (pthread_mutex_init ((pmutex), NULL)))
#elif defined(MHD_W32_MUTEX_)
/**
* Initialise new mutex.
* @param pmutex pointer to mutex
* @return nonzero on success, zero otherwise
*/
-#define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount((pmutex),16))
+#define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount ( \
+ (pmutex),16))
+#endif
+
+#if defined(MHD_PTHREAD_MUTEX_)
+# if defined(PTHREAD_MUTEX_INITIALIZER)
+/**
+ * Define static mutex and statically initialise it.
+ */
+# define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = \
+ PTHREAD_MUTEX_INITIALIZER
+# endif /* PTHREAD_MUTEX_INITIALIZER */
#endif
#if defined(MHD_PTHREAD_MUTEX_)
@@ -91,14 +105,14 @@
* @param pmutex pointer to mutex
* @return nonzero on success, zero otherwise
*/
-#define MHD_mutex_destroy_(pmutex) (!(pthread_mutex_destroy((pmutex))))
+#define MHD_mutex_destroy_(pmutex) (! (pthread_mutex_destroy ((pmutex))))
#elif defined(MHD_W32_MUTEX_)
/**
* Destroy previously initialised mutex.
* @param pmutex pointer to mutex
* @return Always nonzero
*/
-#define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection((pmutex)), !0)
+#define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection ((pmutex)), ! 0)
#endif
/**
@@ -107,9 +121,9 @@
* @param pmutex pointer to mutex
*/
#define MHD_mutex_destroy_chk_(pmutex) do { \
- if (!MHD_mutex_destroy_(pmutex)) \
- MHD_PANIC(_("Failed to destroy mutex.\n")); \
- } while(0)
+ if (! MHD_mutex_destroy_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to destroy mutex.\n")); \
+} while (0)
#if defined(MHD_PTHREAD_MUTEX_)
@@ -120,7 +134,7 @@
* @param pmutex pointer to mutex
* @return nonzero on success, zero otherwise
*/
-#define MHD_mutex_lock_(pmutex) (!(pthread_mutex_lock((pmutex))))
+#define MHD_mutex_lock_(pmutex) (! (pthread_mutex_lock ((pmutex))))
#elif defined(MHD_W32_MUTEX_)
/**
* Acquire lock on previously initialised mutex.
@@ -129,7 +143,7 @@
* @param pmutex pointer to mutex
* @return Always nonzero
*/
-#define MHD_mutex_lock_(pmutex) (EnterCriticalSection((pmutex)), !0)
+#define MHD_mutex_lock_(pmutex) (EnterCriticalSection ((pmutex)), ! 0)
#endif
/**
@@ -140,9 +154,9 @@
* @param pmutex pointer to mutex
*/
#define MHD_mutex_lock_chk_(pmutex) do { \
- if (!MHD_mutex_lock_(pmutex)) \
- MHD_PANIC(_("Failed to lock mutex.\n")); \
- } while(0)
+ if (! MHD_mutex_lock_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to lock mutex.\n")); \
+} while (0)
#if defined(MHD_PTHREAD_MUTEX_)
/**
@@ -150,14 +164,14 @@
* @param pmutex pointer to mutex
* @return nonzero on success, zero otherwise
*/
-#define MHD_mutex_unlock_(pmutex) (!(pthread_mutex_unlock((pmutex))))
+#define MHD_mutex_unlock_(pmutex) (! (pthread_mutex_unlock ((pmutex))))
#elif defined(MHD_W32_MUTEX_)
/**
* Unlock previously initialised and locked mutex.
* @param pmutex pointer to mutex
* @return Always nonzero
*/
-#define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection((pmutex)), !0)
+#define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection ((pmutex)), ! 0)
#endif
/**
@@ -166,9 +180,20 @@
* @param pmutex pointer to mutex
*/
#define MHD_mutex_unlock_chk_(pmutex) do { \
- if (!MHD_mutex_unlock_(pmutex)) \
- MHD_PANIC(_("Failed to unlock mutex.\n")); \
- } while(0)
+ if (! MHD_mutex_unlock_ (pmutex)) \
+ MHD_PANIC (_ ("Failed to unlock mutex.\n")); \
+} while (0)
+
+#else /* ! MHD_USE_THREADS */
+
+#define MHD_mutex_init_(ignore) (! 0)
+#define MHD_mutex_destroy_(ignore) (! 0)
+#define MHD_mutex_destroy_chk_(ignore) (void)0
+#define MHD_mutex_lock_(ignore) (! 0)
+#define MHD_mutex_lock_chk_(ignore) (void)0
+#define MHD_mutex_unlock_(ignore) (! 0)
+#define MHD_mutex_unlock_chk_(ignore) (void)0
+#endif /* ! MHD_USE_THREADS */
#endif /* ! MHD_LOCKS_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_mono_clock.c
^
|
@@ -25,10 +25,10 @@
#include "mhd_mono_clock.h"
-#if defined(_WIN32) && defined(HAVE_CLOCK_GETTIME)
+#if defined(_WIN32) && ! defined(__CYGWIN__) && defined(HAVE_CLOCK_GETTIME)
/* Prefer native clock source over wrappers */
#undef HAVE_CLOCK_GETTIME
-#endif /* _WIN32 && HAVE_CLOCK_GETTIME */
+#endif /* _WIN32 && ! __CYGWIN__ && HAVE_CLOCK_GETTIME */
#ifdef HAVE_CLOCK_GETTIME
#include <time.h>
@@ -76,7 +76,8 @@
#endif /* HAVE_CLOCK_GETTIME */
/* sync clocks; reduce chance of value wrap */
-#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || defined(HAVE_GETHRTIME)
+#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || \
+ defined(HAVE_GETHRTIME)
static time_t mono_clock_start;
#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */
static time_t sys_clock_start;
@@ -93,7 +94,6 @@
#endif /* _WIN32 */
-
/**
* Type of monotonic clock source
*/
@@ -124,9 +124,9 @@
*/
_MHD_CLOCK_GETTICKCOUNT64,
- /**
- * QueryPerformanceCounter() / QueryPerformanceFrequency()
- */
+ /**
+ * QueryPerformanceCounter() / QueryPerformanceFrequency()
+ */
_MHD_CLOCK_PERFCOUNTER
};
@@ -153,8 +153,8 @@
/* just a little syntactic trick to get the
various following ifdef's to work out nicely */
if (0)
- {
- }
+ {
+ }
else
#ifdef HAVE_CLOCK_GETTIME
#ifdef CLOCK_MONOTONIC_COARSE
@@ -163,11 +163,11 @@
/* but preferred since it's fast */
if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE,
&ts))
- {
- mono_clock_id = CLOCK_MONOTONIC_COARSE;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_MONOTONIC_COARSE;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_MONOTONIC_COARSE */
#ifdef CLOCK_MONOTONIC_FAST
@@ -175,11 +175,11 @@
/* Can be affected by frequency adjustment, but preferred since it's fast */
if (0 == clock_gettime (CLOCK_MONOTONIC_FAST,
&ts))
- {
- mono_clock_id = CLOCK_MONOTONIC_FAST;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_MONOTONIC_FAST;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_MONOTONIC_COARSE */
#ifdef CLOCK_MONOTONIC_RAW
@@ -187,11 +187,11 @@
/* Not affected by frequency adjustment, but don't count time in suspend */
if (0 == clock_gettime (CLOCK_MONOTONIC_RAW,
&ts))
- {
- mono_clock_id = CLOCK_MONOTONIC_RAW;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_MONOTONIC_RAW;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_MONOTONIC_RAW */
#ifdef CLOCK_BOOTTIME
@@ -200,11 +200,11 @@
/* but can be slower value-getting than other clocks */
if (0 == clock_gettime (CLOCK_BOOTTIME,
&ts))
- {
- mono_clock_id = CLOCK_BOOTTIME;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_BOOTTIME;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_BOOTTIME */
#ifdef CLOCK_MONOTONIC
@@ -213,11 +213,11 @@
/* On Linux it's not truly monotonic as it doesn't count time in suspend */
if (0 == clock_gettime (CLOCK_MONOTONIC,
&ts))
- {
- mono_clock_id = CLOCK_MONOTONIC;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_MONOTONIC;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_BOOTTIME */
#endif /* HAVE_CLOCK_GETTIME */
@@ -225,15 +225,15 @@
/* Darwin-specific monotonic clock */
/* Should be monotonic as clock_set_time function always unconditionally */
/* failed on latest kernels */
- if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self(),
+ if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self (),
SYSTEM_CLOCK,
&mono_clock_service)) &&
(KERN_SUCCESS == clock_get_time (mono_clock_service,
&cur_time)) )
- {
- mono_clock_start = cur_time.tv_sec;
- mono_clock_source = _MHD_CLOCK_GET_TIME;
- }
+ {
+ mono_clock_start = cur_time.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GET_TIME;
+ }
else
#endif /* HAVE_CLOCK_GET_TIME */
#ifdef _WIN32
@@ -241,25 +241,25 @@
/* W32 Vista or later specific monotonic clock */
/* Available since Vista, ~15ms accuracy */
if (1)
- {
- tick_start = GetTickCount64 ();
- mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64;
- }
+ {
+ tick_start = GetTickCount64 ();
+ mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64;
+ }
else
#else /* _WIN32_WINNT < 0x0600 */
/* W32 specific monotonic clock */
/* Available on Windows 2000 and later */
if (1)
- {
- LARGE_INTEGER freq;
- LARGE_INTEGER perf_counter;
-
- QueryPerformanceFrequency (&freq); /* never fail on XP and later */
- QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
- perf_freq = freq.QuadPart;
- perf_start = perf_counter.QuadPart;
- mono_clock_source = _MHD_CLOCK_PERFCOUNTER;
- }
+ {
+ LARGE_INTEGER freq;
+ LARGE_INTEGER perf_counter;
+
+ QueryPerformanceFrequency (&freq); /* never fail on XP and later */
+ QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
+ perf_freq = freq.QuadPart;
+ perf_start = perf_counter.QuadPart;
+ mono_clock_source = _MHD_CLOCK_PERFCOUNTER;
+ }
else
#endif /* _WIN32_WINNT < 0x0600 */
#endif /* _WIN32 */
@@ -269,11 +269,11 @@
/* Not preferred due to be potentially resource-hungry */
if (0 == clock_gettime (CLOCK_HIGHRES,
&ts))
- {
- mono_clock_id = CLOCK_HIGHRES;
- mono_clock_start = ts.tv_sec;
- mono_clock_source = _MHD_CLOCK_GETTIME;
- }
+ {
+ mono_clock_id = CLOCK_HIGHRES;
+ mono_clock_start = ts.tv_sec;
+ mono_clock_source = _MHD_CLOCK_GETTIME;
+ }
else
#endif /* CLOCK_HIGHRES */
#endif /* HAVE_CLOCK_GETTIME */
@@ -281,26 +281,26 @@
/* HP-UX and Solaris monotonic clock */
/* Not preferred due to be potentially resource-hungry */
if (1)
- {
- hrtime_start = gethrtime ();
- mono_clock_source = _MHD_CLOCK_GETHRTIME;
- }
+ {
+ hrtime_start = gethrtime ();
+ mono_clock_source = _MHD_CLOCK_GETHRTIME;
+ }
else
#endif /* HAVE_GETHRTIME */
- {
- /* no suitable clock source was found */
- mono_clock_source = _MHD_CLOCK_NO_SOURCE;
- }
+ {
+ /* no suitable clock source was found */
+ mono_clock_source = _MHD_CLOCK_NO_SOURCE;
+ }
#ifdef HAVE_CLOCK_GET_TIME
if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) &&
(_MHD_INVALID_CLOCK_SERV != mono_clock_service) )
- {
- /* clock service was initialised but clock_get_time failed */
- mach_port_deallocate (mach_task_self(),
- mono_clock_service);
- mono_clock_service = _MHD_INVALID_CLOCK_SERV;
- }
+ {
+ /* clock service was initialised but clock_get_time failed */
+ mach_port_deallocate (mach_task_self (),
+ mono_clock_service);
+ mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+ }
#else
(void) mono_clock_source; /* avoid compiler warning */
#endif /* HAVE_CLOCK_GET_TIME */
@@ -317,11 +317,11 @@
{
#ifdef HAVE_CLOCK_GET_TIME
if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
- {
- mach_port_deallocate (mach_task_self(),
- mono_clock_service);
- mono_clock_service = _MHD_INVALID_CLOCK_SERV;
- }
+ {
+ mach_port_deallocate (mach_task_self (),
+ mono_clock_service);
+ mono_clock_service = _MHD_INVALID_CLOCK_SERV;
+ }
#endif /* HAVE_CLOCK_GET_TIME */
}
@@ -340,37 +340,38 @@
struct timespec ts;
if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) &&
- (0 == clock_gettime (mono_clock_id ,
+ (0 == clock_gettime (mono_clock_id,
&ts)) )
return ts.tv_sec - mono_clock_start;
#endif /* HAVE_CLOCK_GETTIME */
#ifdef HAVE_CLOCK_GET_TIME
if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
- {
- mach_timespec_t cur_time;
+ {
+ mach_timespec_t cur_time;
- if (KERN_SUCCESS == clock_get_time(mono_clock_service,
- &cur_time))
- return cur_time.tv_sec - mono_clock_start;
- }
+ if (KERN_SUCCESS == clock_get_time (mono_clock_service,
+ &cur_time))
+ return cur_time.tv_sec - mono_clock_start;
+ }
#endif /* HAVE_CLOCK_GET_TIME */
#if defined(_WIN32)
#if _WIN32_WINNT >= 0x0600
if (1)
- return (time_t)(((uint64_t)(GetTickCount64() - tick_start)) / 1000);
+ return (time_t) (((uint64_t) (GetTickCount64 () - tick_start)) / 1000);
#else /* _WIN32_WINNT < 0x0600 */
if (0 != perf_freq)
- {
- LARGE_INTEGER perf_counter;
+ {
+ LARGE_INTEGER perf_counter;
- QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
- return (time_t)(((uint64_t)(perf_counter.QuadPart - perf_start)) / perf_freq);
- }
+ QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
+ return (time_t) (((uint64_t) (perf_counter.QuadPart - perf_start))
+ / perf_freq);
+ }
#endif /* _WIN32_WINNT < 0x0600 */
#endif /* _WIN32 */
#ifdef HAVE_GETHRTIME
if (1)
- return (time_t)(((uint64_t) (gethrtime () - hrtime_start)) / 1000000000);
+ return (time_t) (((uint64_t) (gethrtime () - hrtime_start)) / 1000000000);
#endif /* HAVE_GETHRTIME */
return time (NULL) - sys_clock_start;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_mono_clock.h
^
|
@@ -37,14 +37,14 @@
* Initialise monotonic seconds counter.
*/
void
-MHD_monotonic_sec_counter_init(void);
+MHD_monotonic_sec_counter_init (void);
/**
* Deinitialise monotonic seconds counter by freeing any allocated resources
*/
void
-MHD_monotonic_sec_counter_finish(void);
+MHD_monotonic_sec_counter_finish (void);
/**
@@ -55,6 +55,6 @@
* @return number of seconds from some fixed moment
*/
time_t
-MHD_monotonic_sec_counter(void);
+MHD_monotonic_sec_counter (void);
#endif /* MHD_MONO_CLOCK_H */
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_send.c
^
|
@@ -0,0 +1,1634 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2017,2020 Karlson2k (Evgeny Grin), Full re-write of buffering and
+ pushing, many bugs fixes, optimisations, sendfile() porting
+ Copyright (C) 2019 ng0 <ng0@n0.is>, Initial version of send() wrappers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ */
+
+/**
+ * @file microhttpd/mhd_send.c
+ * @brief Implementation of send() wrappers and helper functions.
+ * @author Karlson2k (Evgeny Grin)
+ * @author ng0 (N. Gillmann)
+ * @author Christian Grothoff
+ */
+
+/* Worth considering for future improvements and additions:
+ * NetBSD has no sendfile or sendfile64. The way to work
+ * with this seems to be to mmap the file and write(2) as
+ * large a chunk as possible to the socket. Alternatively,
+ * use madvise(..., MADV_SEQUENTIAL). */
+
+#include "mhd_send.h"
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#include <sys/sendfile.h>
+#endif /* MHD_LINUX_SOLARIS_SENDFILE */
+#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#endif /* HAVE_FREEBSD_SENDFILE || HAVE_DARWIN_SENDFILE */
+#ifdef HAVE_SYS_PARAM_H
+/* For FreeBSD version identification */
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+#ifdef HAVE_SYSCONF
+#include <unistd.h>
+#endif /* HAVE_SYSCONF */
+#include "mhd_assert.h"
+
+#include "mhd_limits.h"
+
+#ifdef MHD_VECT_SEND
+#if (! defined (HAVE_SENDMSG) || ! defined(MSG_NOSIGNAL)) && \
+ defined (MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
+ defined (MHD_SEND_SPIPE_SUPPRESS_NEEDED)
+#define _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED 1
+#endif /* (!HAVE_SENDMSG || !MSG_NOSIGNAL) &&
+ MHD_SEND_SPIPE_SUPPRESS_POSSIBLE && MHD_SEND_SPIPE_SUPPRESS_NEEDED */
+#endif /* MHD_VECT_SEND */
+
+/**
+ * sendfile() chuck size
+ */
+#define MHD_SENFILE_CHUNK_ (0x20000)
+
+/**
+ * sendfile() chuck size for thread-per-connection
+ */
+#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
+
+#ifdef HAVE_FREEBSD_SENDFILE
+#ifdef SF_FLAGS
+/**
+ * FreeBSD sendfile() flags
+ */
+static int freebsd_sendfile_flags_;
+
+/**
+ * FreeBSD sendfile() flags for thread-per-connection
+ */
+static int freebsd_sendfile_flags_thd_p_c_;
+
+
+/**
+ * Initialises variables for FreeBSD's sendfile()
+ */
+static void
+freebsd_sendfile_init_ (void)
+{
+ long sys_page_size = sysconf (_SC_PAGESIZE);
+ if (0 >= sys_page_size)
+ { /* Failed to get page size. */
+ freebsd_sendfile_flags_ = SF_NODISKIO;
+ freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
+ }
+ else
+ {
+ freebsd_sendfile_flags_ =
+ SF_FLAGS ((uint16_t) ((MHD_SENFILE_CHUNK_ + sys_page_size - 1)
+ / sys_page_size), SF_NODISKIO);
+ freebsd_sendfile_flags_thd_p_c_ =
+ SF_FLAGS ((uint16_t) ((MHD_SENFILE_CHUNK_THR_P_C_ + sys_page_size - 1)
+ / sys_page_size), SF_NODISKIO);
+ }
+}
+
+
+#endif /* SF_FLAGS */
+#endif /* HAVE_FREEBSD_SENDFILE */
+
+
+#if defined(HAVE_SYSCONF) && defined(_SC_IOV_MAX)
+/**
+ * Current IOV_MAX system value
+ */
+static unsigned long mhd_iov_max_ = 0;
+
+static void
+iov_max_init_ (void)
+{
+ long res = sysconf (_SC_IOV_MAX);
+ if (res >= 0)
+ mhd_iov_max_ = res;
+#if defined(IOV_MAX)
+ else
+ mhd_iov_max_ = IOV_MAX;
+#endif /* IOV_MAX */
+}
+
+
+/**
+ * IOV_MAX (run-time) value
+ */
+#define _MHD_IOV_MAX mhd_iov_max_
+#elif defined(IOV_MAX)
+
+/**
+ * IOV_MAX (static) value
+ */
+#define _MHD_IOV_MAX IOV_MAX
+#endif /* HAVE_SYSCONF && _SC_IOV_MAX */
+
+
+/**
+ * Initialises static variables
+ */
+void
+MHD_send_init_static_vars_ (void)
+{
+#ifdef HAVE_FREEBSD_SENDFILE
+ /* FreeBSD 11 and later allow to specify read-ahead size
+ * and handles SF_NODISKIO differently.
+ * SF_FLAGS defined only on FreeBSD 11 and later. */
+#ifdef SF_FLAGS
+ freebsd_sendfile_init_ ();
+#endif /* SF_FLAGS */
+#endif /* HAVE_FREEBSD_SENDFILE */
+#if defined(HAVE_SYSCONF) && defined(_SC_IOV_MAX)
+ iov_max_init_ ();
+#endif /* HAVE_SYSCONF && _SC_IOV_MAX */
+}
+
+
+bool
+MHD_connection_set_nodelay_state_ (struct MHD_Connection *connection,
+ bool nodelay_state)
+{
+#ifdef TCP_NODELAY
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+ const MHD_SCKT_OPT_BOOL_ on_val = 1;
+ int err_code;
+
+ if (_MHD_YES == connection->is_nonip)
+ return false;
+
+ if (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) (nodelay_state ? &on_val : &off_val),
+ sizeof (off_val)))
+ {
+ connection->sk_nodelay = nodelay_state;
+ return true;
+ }
+
+ err_code = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_EINVAL_) ||
+ MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_ENOPROTOOPT_) ||
+ MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_ENOTSOCK_))
+ {
+ if (_MHD_UNKNOWN == connection->is_nonip)
+ connection->is_nonip = _MHD_YES;
+#ifdef HAVE_MESSAGES
+ else
+ {
+ MHD_DLOG (connection->daemon,
+ _ ("Setting %s option to %s state failed "
+ "for TCP/IP socket %d: %s\n"),
+ "TCP_NODELAY",
+ nodelay_state ? _ ("ON") : _ ("OFF"),
+ (int) connection->socket_fd,
+ MHD_socket_strerr_ (err_code));
+ }
+#endif /* HAVE_MESSAGES */
+ }
+#ifdef HAVE_MESSAGES
+ else
+ {
+ MHD_DLOG (connection->daemon,
+ _ ("Setting %s option to %s state failed: %s\n"),
+ "TCP_NODELAY",
+ nodelay_state ? _ ("ON") : _ ("OFF"),
+ MHD_socket_strerr_ (err_code));
+ }
+#endif /* HAVE_MESSAGES */
+
+#else /* ! TCP_NODELAY */
+ (void) connection; (void) nodelay_state; /* Mute compiler warnings */
+#endif /* ! TCP_NODELAY */
+ return false;
+}
+
+
+/**
+ * Set required cork state for connection socket
+ *
+ * The function automatically updates sk_corked state.
+ *
+ * @param connection the connection to manipulate
+ * @param cork_state the requested new state of socket
+ * @return true if succeed, false if failed or not supported
+ * by the current platform / kernel.
+ */
+bool
+MHD_connection_set_cork_state_ (struct MHD_Connection *connection,
+ bool cork_state)
+{
+#if defined(MHD_TCP_CORK_NOPUSH)
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+ const MHD_SCKT_OPT_BOOL_ on_val = 1;
+ int err_code;
+
+ if (_MHD_YES == connection->is_nonip)
+ return false;
+ if (0 == setsockopt (connection->socket_fd,
+ IPPROTO_TCP,
+ MHD_TCP_CORK_NOPUSH,
+ (const void *) (cork_state ? &on_val : &off_val),
+ sizeof (off_val)))
+ {
+ connection->sk_corked = cork_state;
+ return true;
+ }
+
+ err_code = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_EINVAL_) ||
+ MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_ENOPROTOOPT_) ||
+ MHD_SCKT_ERR_IS_ (err_code, MHD_SCKT_ENOTSOCK_))
+ {
+ if (_MHD_UNKNOWN == connection->is_nonip)
+ connection->is_nonip = _MHD_YES;
+#ifdef HAVE_MESSAGES
+ else
+ {
+ MHD_DLOG (connection->daemon,
+ _ ("Setting %s option to %s state failed "
+ "for TCP/IP socket %d: %s\n"),
+#ifdef TCP_CORK
+ "TCP_CORK",
+#else /* ! TCP_CORK */
+ "TCP_NOPUSH",
+#endif /* ! TCP_CORK */
+ cork_state ? _ ("ON") : _ ("OFF"),
+ (int) connection->socket_fd,
+ MHD_socket_strerr_ (err_code));
+ }
+#endif /* HAVE_MESSAGES */
+ }
+#ifdef HAVE_MESSAGES
+ else
+ {
+ MHD_DLOG (connection->daemon,
+ _ ("Setting %s option to %s state failed: %s\n"),
+#ifdef TCP_CORK
+ "TCP_CORK",
+#else /* ! TCP_CORK */
+ "TCP_NOPUSH",
+#endif /* ! TCP_CORK */
+ cork_state ? _ ("ON") : _ ("OFF"),
+ MHD_socket_strerr_ (err_code));
+ }
+#endif /* HAVE_MESSAGES */
+
+#else /* ! MHD_TCP_CORK_NOPUSH */
+ (void) connection; (void) cork_state; /* Mute compiler warnings. */
+#endif /* ! MHD_TCP_CORK_NOPUSH */
+ return false;
+}
+
+
+/**
+ * Handle pre-send setsockopt calls.
+ *
+ * @param connection the MHD_Connection structure
+ * @param plain_send set to true if plain send() or sendmsg() will be called,
+ * set to false if TLS socket send(), sendfile() or
+ * writev() will be called.
+ * @param push_data whether to push data to the network from buffers after
+ * the next call of send function.
+ */
+static void
+pre_send_setopt (struct MHD_Connection *connection,
+ bool plain_send,
+ bool push_data)
+{
+ /* Try to buffer data if not sending the final piece.
+ * Final piece is indicated by push_data == true. */
+ const bool buffer_data = (! push_data);
+
+ if (_MHD_YES == connection->is_nonip)
+ return;
+ /* The goal is to minimise the total number of additional sys-calls
+ * before and after send().
+ * The following tricky (over-)complicated algorithm typically use zero,
+ * one or two additional sys-calls (depending on OS) for each response. */
+
+ if (buffer_data)
+ {
+ /* Need to buffer data if possible. */
+#ifdef MHD_USE_MSG_MORE
+ if (plain_send)
+ return; /* Data is buffered by send() with MSG_MORE flag.
+ * No need to check or change anything. */
+#else /* ! MHD_USE_MSG_MORE */
+ (void) plain_send; /* Mute compiler warning. */
+#endif /* ! MHD_USE_MSG_MORE */
+
+#ifdef MHD_TCP_CORK_NOPUSH
+ if (_MHD_ON == connection->sk_corked)
+ return; /* The connection was already corked. */
+
+ if (MHD_connection_set_cork_state_ (connection, true))
+ return; /* The connection has been corked. */
+
+ /* Failed to cork the connection.
+ * Really unlikely to happen on TCP connections. */
+#endif /* MHD_TCP_CORK_NOPUSH */
+ if (_MHD_OFF == connection->sk_nodelay)
+ return; /* TCP_NODELAY was not set for the socket.
+ * Nagle's algorithm will buffer some data. */
+
+ /* Try to reset TCP_NODELAY state for the socket.
+ * Ignore possible error as no other options exist to
+ * buffer data. */
+ MHD_connection_set_nodelay_state_ (connection, false);
+ /* TCP_NODELAY has been (hopefully) reset for the socket.
+ * Nagle's algorithm will buffer some data. */
+ return;
+ }
+
+ /* Need to push data after send() */
+ /* If additional sys-call is required prefer to make it after the send()
+ * as the next send() may consume only part of the prepared data and
+ * more send() calls will be used. */
+#ifdef MHD_TCP_CORK_NOPUSH
+#ifdef _MHD_CORK_RESET_PUSH_DATA
+#ifdef _MHD_CORK_RESET_PUSH_DATA_ALWAYS
+ /* Data can be pushed immediately by uncorking socket regardless of
+ * cork state before. */
+ /* This is typical for Linux, no other kernel with
+ * such behavior are known so far. */
+
+ /* No need to check the current state of TCP_CORK / TCP_NOPUSH
+ * as reset of cork will push the data anyway. */
+ return; /* Data may be pushed by resetting of
+ * TCP_CORK / TCP_NOPUSH after send() */
+#else /* ! _MHD_CORK_RESET_PUSH_DATA_ALWAYS */
+ /* Reset of TCP_CORK / TCP_NOPUSH will push the data
+ * only if socket is corked. */
+
+#ifdef _MHD_NODELAY_SET_PUSH_DATA_ALWAYS
+ /* Data can be pushed immediately by setting TCP_NODELAY regardless
+ * of TCP_NODDELAY or corking state before. */
+
+ /* Dead code currently, no known kernels with such behavior. */
+ return; /* Data may be pushed by setting of TCP_NODELAY after send().
+ No need to make extra sys-calls before send().*/
+#else /* ! _MHD_NODELAY_SET_PUSH_DATA_ALWAYS */
+
+#ifdef _MHD_NODELAY_SET_PUSH_DATA
+ /* Setting of TCP_NODELAY will push the data only if
+ * both TCP_NODELAY and TCP_CORK / TCP_NOPUSH were not set. */
+
+ /* Data can be pushed immediately by uncorking socket if
+ * socket was corked before or by setting TCP_NODELAY if
+ * socket was not corked and TCP_NODELAY was not set before. */
+
+ /* Dead code currently as Linux is the only kernel that push
+ * data by setting of TCP_NODELAY and Linux push data always. */
+#else /* ! _MHD_NODELAY_SET_PUSH_DATA */
+ /* Data can be pushed immediately by uncorking socket or
+ * can be pushed by send() on uncorked socket if
+ * TCP_NODELAY was set *before*. */
+
+ /* This is typical FreeBSD behavior. */
+#endif /* ! _MHD_NODELAY_SET_PUSH_DATA */
+
+ if (_MHD_ON == connection->sk_corked)
+ return; /* Socket is corked. Data can be pushed by resetting of
+ * TCP_CORK / TCP_NOPUSH after send() */
+ else if (_MHD_OFF == connection->sk_corked)
+ {
+ /* The socket is not corked. */
+ if (_MHD_ON == connection->sk_nodelay)
+ return; /* TCP_NODELAY was already set,
+ * data will be pushed automatically by the next send() */
+#ifdef _MHD_NODELAY_SET_PUSH_DATA
+ else if (_MHD_UNKNOWN == connection->sk_nodelay)
+ {
+ /* Setting TCP_NODELAY may push data.
+ * Cork socket here and uncork after send(). */
+ if (MHD_connection_set_cork_state_ (connection, true))
+ return; /* The connection has been corked.
+ * Data can be pushed by resetting of
+ * TCP_CORK / TCP_NOPUSH after send() */
+ else
+ {
+ /* The socket cannot be corked.
+ * Really unlikely to happen on TCP connections */
+ /* Have to set TCP_NODELAY.
+ * If TCP_NODELAY real system state was OFF then
+ * already buffered data may be pushed here, but this is unlikely
+ * to happen as it is only a backup solution when corking has failed.
+ * Ignore possible error here as no other options exist to
+ * push data. */
+ MHD_connection_set_nodelay_state_ (connection, true);
+ /* TCP_NODELAY has been (hopefully) set for the socket.
+ * The data will be pushed by the next send(). */
+ return;
+ }
+ }
+#endif /* _MHD_NODELAY_SET_PUSH_DATA */
+ else
+ {
+#ifdef _MHD_NODELAY_SET_PUSH_DATA
+ /* TCP_NODELAY was switched off and
+ * the socket is not corked. */
+#else /* ! _MHD_NODELAY_SET_PUSH_DATA */
+ /* Socket is not corked and TCP_NODELAY was not set or unknown. */
+#endif /* ! _MHD_NODELAY_SET_PUSH_DATA */
+
+ /* At least one additional sys-call is required. */
+ /* Setting TCP_NODELAY is optimal here as data will be pushed
+ * automatically by the next send() and no additional
+ * sys-call are needed after the send(). */
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ return;
+ else
+ {
+ /* Failed to set TCP_NODELAY for the socket.
+ * Really unlikely to happen on TCP connections. */
+ /* Cork the socket here and make additional sys-call
+ * to uncork the socket after send(). */
+ /* Ignore possible error here as no other options exist to
+ * push data. */
+ MHD_connection_set_cork_state_ (connection, true);
+ /* The connection has been (hopefully) corked.
+ * Data can be pushed by resetting of TCP_CORK / TCP_NOPUSH
+ * after send() */
+ return;
+ }
+ }
+ }
+ /* Corked state is unknown. Need to make sys-call here otherwise
+ * data may not be pushed. */
+ if (MHD_connection_set_cork_state_ (connection, true))
+ return; /* The connection has been corked.
+ * Data can be pushed by resetting of
+ * TCP_CORK / TCP_NOPUSH after send() */
+ /* The socket cannot be corked.
+ * Really unlikely to happen on TCP connections */
+ if (_MHD_ON == connection->sk_nodelay)
+ return; /* TCP_NODELAY was already set,
+ * data will be pushed by the next send() */
+ /* Have to set TCP_NODELAY. */
+#ifdef _MHD_NODELAY_SET_PUSH_DATA
+ /* If TCP_NODELAY state was unknown (external connection) then
+ * already buffered data may be pushed here, but this is unlikely
+ * to happen as it is only a backup solution when corking has failed. */
+#endif /* _MHD_NODELAY_SET_PUSH_DATA */
+ /* Ignore possible error here as no other options exist to
+ * push data. */
+ MHD_connection_set_nodelay_state_ (connection, true);
+ /* TCP_NODELAY has been (hopefully) set for the socket.
+ * The data will be pushed by the next send(). */
+ return;
+#endif /* ! _MHD_NODELAY_SET_PUSH_DATA_ALWAYS */
+#endif /* ! _MHD_CORK_RESET_PUSH_DATA_ALWAYS */
+#else /* ! _MHD_CORK_RESET_PUSH_DATA */
+ /* Neither uncorking the socket or setting TCP_NODELAY
+ * push the data immediately. */
+ /* The only way to push the data is to use send() on uncorked
+ * socket with TCP_NODELAY switched on . */
+
+ /* This is a typical *BSD (except FreeBSD) and Darwin behavior. */
+
+ /* Uncork socket if socket wasn't uncorked. */
+ if (_MHD_OFF != connection->sk_corked)
+ MHD_connection_set_cork_state_ (connection, false);
+
+ /* Set TCP_NODELAY if it wasn't set. */
+ if (_MHD_ON != connection->sk_nodelay)
+ MHD_connection_set_nodelay_state_ (connection, true);
+
+ return;
+#endif /* ! _MHD_CORK_RESET_PUSH_DATA */
+#else /* ! MHD_TCP_CORK_NOPUSH */
+ /* Buffering of data is controlled only by
+ * Nagel's algorithm. */
+ /* Set TCP_NODELAY if it wasn't set. */
+ if (_MHD_ON != connection->sk_nodelay)
+ MHD_connection_set_nodelay_state_ (connection, true);
+#endif /* ! MHD_TCP_CORK_NOPUSH */
+}
+
+
+#ifndef _MHD_CORK_RESET_PUSH_DATA_ALWAYS
+/**
+ * Send zero-sized data
+ *
+ * This function use send of zero-sized data to kick data from the socket
+ * buffers to the network. The socket must not be corked and must have
+ * TCP_NODELAY switched on.
+ * Used only as last resort option, when other options are failed due to
+ * some errors.
+ * Should not be called on typical data processing.
+ * @return true if succeed, false if failed
+ */
+static bool
+zero_send_ (struct MHD_Connection *connection)
+{
+ int dummy;
+
+ if (_MHD_YES == connection->is_nonip)
+ return false;
+ mhd_assert (_MHD_OFF == connection->sk_corked);
+ mhd_assert (_MHD_ON == connection->sk_nodelay);
+ dummy = 0; /* Mute compiler and analyzer warnings */
+ if (0 == MHD_send_ (connection->socket_fd, &dummy, 0))
+ return true;
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Zero-send failed: %s\n"),
+ MHD_socket_last_strerr_ () );
+#endif /* HAVE_MESSAGES */
+ return false;
+}
+
+
+#endif /* ! _MHD_CORK_RESET_PUSH_DATA_ALWAYS */
+
+/**
+ * Handle post-send setsockopt calls.
+ *
+ * @param connection the MHD_Connection structure
+ * @param plain_send_next set to true if plain send() or sendmsg() will be
+ * called next,
+ * set to false if TLS socket send(), sendfile() or
+ * writev() will be called next.
+ * @param push_data whether to push data to the network from buffers
+ */
+static void
+post_send_setopt (struct MHD_Connection *connection,
+ bool plain_send_next,
+ bool push_data)
+{
+ /* Try to buffer data if not sending the final piece.
+ * Final piece is indicated by push_data == true. */
+ const bool buffer_data = (! push_data);
+
+ if (_MHD_YES == connection->is_nonip)
+ return;
+ if (buffer_data)
+ return; /* Nothing to do after send(). */
+
+#ifndef MHD_USE_MSG_MORE
+ (void) plain_send_next; /* Mute compiler warning */
+#endif /* ! MHD_USE_MSG_MORE */
+
+ /* Need to push data. */
+#ifdef MHD_TCP_CORK_NOPUSH
+#ifdef _MHD_CORK_RESET_PUSH_DATA_ALWAYS
+#ifdef _MHD_NODELAY_SET_PUSH_DATA_ALWAYS
+#ifdef MHD_USE_MSG_MORE
+ if (_MHD_OFF == connection->sk_corked)
+ {
+ if (_MHD_ON == connection->sk_nodelay)
+ return; /* Data was already pushed by send(). */
+ }
+ /* This is Linux kernel. There are options:
+ * * Push the data by setting of TCP_NODELAY (without change
+ * of the cork on the socket),
+ * * Push the data by resetting of TCP_CORK.
+ * The optimal choice depends on the next final send functions
+ * used on the same socket. If TCP_NODELAY wasn't set then push
+ * data by setting TCP_NODELAY (TCP_NODELAY will not be removed
+ * and is needed to push the data by send() without MSG_MORE).
+ * If send()/sendmsg() will be used next than push data by
+ * resetting of TCP_CORK so next send without MSG_MORE will push
+ * data to the network (without additional sys-call to push data).
+ * If next final send function will not support MSG_MORE (like
+ * sendfile() or TLS-connection) than push data by setting
+ * TCP_NODELAY so socket will remain corked (no additional
+ * sys-call before next send()). */
+ if ((_MHD_ON != connection->sk_nodelay) ||
+ (! plain_send_next))
+ {
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ return; /* Data has been pushed by TCP_NODELAY. */
+ /* Failed to set TCP_NODELAY for the socket.
+ * Really unlikely to happen on TCP connections. */
+ if (MHD_connection_set_cork_state_ (connection, false))
+ return; /* Data has been pushed by uncorking the socket. */
+ /* Failed to uncork the socket.
+ * Really unlikely to happen on TCP connections. */
+
+ /* The socket cannot be uncorked, no way to push data */
+ }
+ else
+ {
+ if (MHD_connection_set_cork_state_ (connection, false))
+ return; /* Data has been pushed by uncorking the socket. */
+ /* Failed to uncork the socket.
+ * Really unlikely to happen on TCP connections. */
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ return; /* Data has been pushed by TCP_NODELAY. */
+ /* Failed to set TCP_NODELAY for the socket.
+ * Really unlikely to happen on TCP connections. */
+
+ /* The socket cannot be uncorked, no way to push data */
+ }
+#else /* ! MHD_USE_MSG_MORE */
+ /* Use setting of TCP_NODELAY here to avoid sys-call
+ * for corking the socket during sending of the next response. */
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ return; /* Data was pushed by TCP_NODELAY. */
+ /* Failed to set TCP_NODELAY for the socket.
+ * Really unlikely to happen on TCP connections. */
+ if (MHD_connection_set_cork_state_ (connection, false))
+ return; /* Data was pushed by uncorking the socket. */
+ /* Failed to uncork the socket.
+ * Really unlikely to happen on TCP connections. */
+
+ /* The socket remains corked, no way to push data */
+#endif /* ! MHD_USE_MSG_MORE */
+#else /* ! _MHD_NODELAY_SET_PUSH_DATA_ALWAYS */
+ if (MHD_connection_set_cork_state_ (connection, false))
+ return; /* Data was pushed by uncorking the socket. */
+ /* Failed to uncork the socket.
+ * Really unlikely to happen on TCP connections. */
+ return; /* Socket remains corked, no way to push data */
+#endif /* ! _MHD_NODELAY_SET_PUSH_DATA_ALWAYS */
+#else /* ! _MHD_CORK_RESET_PUSH_DATA_ALWAYS */
+ /* This is a typical *BSD or Darwin kernel. */
+
+ if (_MHD_OFF == connection->sk_corked)
+ {
+ if (_MHD_ON == connection->sk_nodelay)
+ return; /* Data was already pushed by send(). */
+
+ /* Unlikely to reach this code.
+ * TCP_NODELAY should be turned on before send(). */
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ {
+ /* TCP_NODELAY has been set on uncorked socket.
+ * Use zero-send to push the data. */
+ if (zero_send_ (connection))
+ return; /* The data has been pushed by zero-send. */
+ }
+
+ /* Failed to push the data by all means. */
+ /* There is nothing left to try. */
+ }
+ else
+ {
+#ifdef _MHD_CORK_RESET_PUSH_DATA
+ enum MHD_tristate old_cork_state = connection->sk_corked;
+#endif /* _MHD_CORK_RESET_PUSH_DATA */
+ /* The socket is corked or cork state is unknown. */
+
+ if (MHD_connection_set_cork_state_ (connection, false))
+ {
+#ifdef _MHD_CORK_RESET_PUSH_DATA
+ /* FreeBSD kernel */
+ if (_MHD_OFF == old_cork_state)
+ return; /* Data has been pushed by uncorking the socket. */
+#endif /* _MHD_CORK_RESET_PUSH_DATA */
+
+ /* Unlikely to reach this code.
+ * The data should be pushed by uncorking (FreeBSD) or
+ * the socket should be uncorked before send(). */
+ if ((_MHD_ON == connection->sk_nodelay) ||
+ (MHD_connection_set_nodelay_state_ (connection, true)))
+ {
+ /* TCP_NODELAY is turned ON on uncorked socket.
+ * Use zero-send to push the data. */
+ if (zero_send_ (connection))
+ return; /* The data has been pushed by zero-send. */
+ }
+ }
+ /* The socket remains corked. Data cannot be pushed. */
+ }
+#endif /* ! _MHD_CORK_RESET_PUSH_DATA_ALWAYS */
+#else /* ! MHD_TCP_CORK_NOPUSH */
+ /* Corking is not supported. Buffering is controlled
+ * by TCP_NODELAY only. */
+ mhd_assert (_MHD_ON != connection->sk_corked);
+ if (_MHD_ON == connection->sk_nodelay)
+ return; /* Data was already pushed by send(). */
+
+ /* Unlikely to reach this code.
+ * TCP_NODELAY should be turned on before send(). */
+ if (MHD_connection_set_nodelay_state_ (connection, true))
+ {
+ /* TCP_NODELAY has been set.
+ * Use zero-send to push the data. */
+ if (zero_send_ (connection))
+ return; /* The data has been pushed by zero-send. */
+ }
+
+ /* Failed to push the data. */
+#endif /* ! MHD_TCP_CORK_NOPUSH */
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (connection->daemon,
+ _ ("Failed to push the data from buffers to the network. "
+ "Client may experience some delay "
+ "(usually in range 200ms - 5 sec).\n"));
+#endif /* HAVE_MESSAGES */
+ return;
+}
+
+
+ssize_t
+MHD_send_data_ (struct MHD_Connection *connection,
+ const char *buffer,
+ size_t buffer_size,
+ bool push_data)
+{
+ MHD_socket s = connection->socket_fd;
+ ssize_t ret;
+#ifdef HTTPS_SUPPORT
+ const bool tls_conn = (connection->daemon->options & MHD_USE_TLS);
+#else /* ! HTTPS_SUPPORT */
+ const bool tls_conn = false;
+#endif /* ! HTTPS_SUPPORT */
+
+ if ( (MHD_INVALID_SOCKET == s) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+
+ if (buffer_size > SSIZE_MAX)
+ {
+ buffer_size = SSIZE_MAX; /* Max return value */
+ push_data = false; /* Incomplete send */
+ }
+
+ if (tls_conn)
+ {
+#ifdef HTTPS_SUPPORT
+ pre_send_setopt (connection, (! tls_conn), push_data);
+ ret = gnutls_record_send (connection->tls_session,
+ buffer,
+ buffer_size);
+ if (GNUTLS_E_AGAIN == ret)
+ {
+#ifdef EPOLL_SUPPORT
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif
+ return MHD_ERR_AGAIN_;
+ }
+ if (GNUTLS_E_INTERRUPTED == ret)
+ return MHD_ERR_AGAIN_;
+ if ( (GNUTLS_E_ENCRYPTION_FAILED == ret) ||
+ (GNUTLS_E_INVALID_SESSION == ret) ||
+ (GNUTLS_E_COMPRESSION_FAILED == ret) ||
+ (GNUTLS_E_EXPIRED == ret) ||
+ (GNUTLS_E_HASH_FAILED == ret) )
+ return MHD_ERR_TLS_;
+ if ( (GNUTLS_E_PUSH_ERROR == ret) ||
+ (GNUTLS_E_INTERNAL_ERROR == ret) ||
+ (GNUTLS_E_CRYPTODEV_IOCTL_ERROR == ret) ||
+ (GNUTLS_E_CRYPTODEV_DEVICE_ERROR == ret) )
+ return MHD_ERR_PIPE_;
+ if (GNUTLS_E_PREMATURE_TERMINATION == ret)
+ return MHD_ERR_CONNRESET_;
+ if (GNUTLS_E_MEMORY_ERROR == ret)
+ return MHD_ERR_NOMEM_;
+ if (ret < 0)
+ {
+ /* Treat any other error as hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#ifdef EPOLL_SUPPORT
+ /* Unlike non-TLS connections, do not reset "write-ready" if
+ * sent amount smaller than provided amount, as TLS
+ * connections may break data into smaller parts for sending. */
+#endif /* EPOLL_SUPPORT */
+#endif /* HTTPS_SUPPORT */
+ (void) 0; /* Mute compiler warning for non-TLS builds. */
+ }
+ else
+ {
+ /* plaintext transmission */
+ if (buffer_size > MHD_SCKT_SEND_MAX_SIZE_)
+ {
+ buffer_size = MHD_SCKT_SEND_MAX_SIZE_; /* send() return value limit */
+ push_data = false; /* Incomplete send */
+ }
+
+ pre_send_setopt (connection, (! tls_conn), push_data);
+#ifdef MHD_USE_MSG_MORE
+ ret = MHD_send4_ (s,
+ buffer,
+ buffer_size,
+ push_data ? 0 : MSG_MORE);
+#else
+ ret = MHD_send4_ (s,
+ buffer,
+ buffer_size,
+ 0);
+#endif
+
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#if EPOLL_SUPPORT
+ /* EAGAIN, no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
+ return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EPIPE_))
+ return MHD_ERR_PIPE_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EOPNOTSUPP_))
+ return MHD_ERR_OPNOTSUPP_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ENOTCONN_))
+ return MHD_ERR_NOTCONN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EINVAL_))
+ return MHD_ERR_INVAL_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* Treat any other error as a hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#if EPOLL_SUPPORT
+ else if (buffer_size > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ }
+
+ /* If there is a need to push the data from network buffers
+ * call post_send_setopt(). */
+ /* If TLS connection is used then next final send() will be
+ * without MSG_MORE support. If non-TLS connection is used
+ * it's unknown whether sendfile() will be used or not so
+ * assume that next call will be the same, like this call. */
+ if ( (push_data) &&
+ (buffer_size == (size_t) ret) )
+ post_send_setopt (connection, (! tls_conn), push_data);
+
+ return ret;
+}
+
+
+ssize_t
+MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
+ const char *header,
+ size_t header_size,
+ bool never_push_hdr,
+ const char *body,
+ size_t body_size,
+ bool complete_response)
+{
+ ssize_t ret;
+ bool push_hdr;
+ bool push_body;
+ MHD_socket s = connection->socket_fd;
+#ifndef _WIN32
+#define _MHD_SEND_VEC_MAX MHD_SCKT_SEND_MAX_SIZE_
+#else /* ! _WIN32 */
+#define _MHD_SEND_VEC_MAX UINT32_MAX
+#endif /* ! _WIN32 */
+#ifdef MHD_VECT_SEND
+#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
+ struct iovec vector[2];
+#ifdef HAVE_SENDMSG
+ struct msghdr msg;
+#endif /* HAVE_SENDMSG */
+#endif /* HAVE_SENDMSG || HAVE_WRITEV */
+#ifdef _WIN32
+ WSABUF vector[2];
+ DWORD vec_sent;
+#endif /* _WIN32 */
+ bool no_vec; /* Is vector-send() disallowed? */
+
+ no_vec = false;
+#ifdef HTTPS_SUPPORT
+ no_vec = no_vec || (connection->daemon->options & MHD_USE_TLS);
+#endif /* HTTPS_SUPPORT */
+#if (! defined(HAVE_SENDMSG) || ! defined(MSG_NOSIGNAL) ) && \
+ defined(MHD_SEND_SPIPE_SEND_SUPPRESS_POSSIBLE) && \
+ defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
+ no_vec = no_vec || (! connection->daemon->sigpipe_blocked &&
+ ! connection->sk_spipe_suppress);
+#endif /* (!HAVE_SENDMSG || ! MSG_NOSIGNAL) &&
+ MHD_SEND_SPIPE_SEND_SUPPRESS_POSSIBLE &&
+ MHD_SEND_SPIPE_SUPPRESS_NEEDED */
+#endif /* MHD_VECT_SEND */
+
+ mhd_assert ( (NULL != body) || (0 == body_size) );
+
+ if ( (MHD_INVALID_SOCKET == s) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+
+ push_body = complete_response;
+
+ if (! never_push_hdr)
+ {
+ if (! complete_response)
+ push_hdr = true; /* Push the header as the client may react
+ * on header alone while the body data is
+ * being prepared. */
+ else
+ {
+ if (1400 > (header_size + body_size))
+ push_hdr = false; /* Do not push the header as complete
+ * reply is already ready and the whole
+ * reply most probably will fit into
+ * the single IP packet. */
+ else
+ push_hdr = true; /* Push header alone so client may react
+ * on it while reply body is being delivered. */
+ }
+ }
+ else
+ push_hdr = false;
+
+ if (complete_response && (0 == body_size))
+ push_hdr = true; /* The header alone is equal to the whole response. */
+
+ if (
+#ifdef MHD_VECT_SEND
+ (no_vec) ||
+ (0 == body_size) ||
+ ((size_t) SSIZE_MAX <= header_size) ||
+ ((size_t) _MHD_SEND_VEC_MAX < header_size)
+#ifdef _WIN32
+ || ((size_t) UINT_MAX < header_size)
+#endif /* _WIN32 */
+#else /* ! MHD_VECT_SEND */
+ true
+#endif /* ! MHD_VECT_SEND */
+ )
+ {
+ ret = MHD_send_data_ (connection,
+ header,
+ header_size,
+ push_hdr);
+
+ if ( (header_size == (size_t) ret) &&
+ ((size_t) SSIZE_MAX > header_size) &&
+ (0 != body_size) &&
+ (connection->sk_nonblck) )
+ {
+ ssize_t ret2;
+ /* The header has been sent completely.
+ * Try to send the reply body without waiting for
+ * the next round. */
+ /* Make sure that sum of ret + ret2 will not exceed SSIZE_MAX as
+ * function needs to return positive value if succeed. */
+ if ( (((size_t) SSIZE_MAX) - ((size_t) ret)) < body_size)
+ {
+ body_size = (((size_t) SSIZE_MAX) - ((size_t) ret));
+ complete_response = false;
+ push_body = complete_response;
+ }
+
+ ret2 = MHD_send_data_ (connection,
+ body,
+ body_size,
+ push_body);
+ if (0 < ret2)
+ return ret + ret2; /* Total data sent */
+ if (MHD_ERR_AGAIN_ == ret2)
+ return ret;
+
+ return ret2; /* Error code */
+ }
+ return ret;
+ }
+#ifdef MHD_VECT_SEND
+
+ if ( ((size_t) SSIZE_MAX <= body_size) ||
+ ((size_t) SSIZE_MAX < (header_size + body_size)) )
+ {
+ /* Return value limit */
+ body_size = SSIZE_MAX - header_size;
+ complete_response = false;
+ push_body = complete_response;
+ }
+#if (SSIZE_MAX != _MHD_SEND_VEC_MAX) || (_MHD_SEND_VEC_MAX + 0 == 0)
+ if (((size_t) _MHD_SEND_VEC_MAX <= body_size) ||
+ ((size_t) _MHD_SEND_VEC_MAX < (header_size + body_size)))
+ {
+ /* Send total amount limit */
+ body_size = _MHD_SEND_VEC_MAX - header_size;
+ complete_response = false;
+ push_body = complete_response;
+ }
+#endif /* SSIZE_MAX != _MHD_SEND_VEC_MAX */
+
+ pre_send_setopt (connection,
+#ifdef HAVE_SENDMSG
+ true,
+#else /* ! HAVE_SENDMSG */
+ false,
+#endif /* ! HAVE_SENDMSG */
+ push_hdr || push_body);
+#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
+ vector[0].iov_base = (void *) header;
+ vector[0].iov_len = header_size;
+ vector[1].iov_base = (void *) body;
+ vector[1].iov_len = body_size;
+
+#if defined(HAVE_SENDMSG)
+ memset (&msg, 0, sizeof(msg));
+ msg.msg_iov = vector;
+ msg.msg_iovlen = 2;
+
+ ret = sendmsg (s, &msg, MSG_NOSIGNAL_OR_ZERO);
+#elif defined (HAVE_WRITEV)
+ ret = writev (s, vector, 2);
+#endif /* HAVE_WRITEV */
+#endif /* HAVE_SENDMSG || HAVE_WRITEV */
+#ifdef _WIN32
+ if ((size_t) UINT_MAX < body_size)
+ {
+ /* Send item size limit */
+ body_size = UINT_MAX;
+ complete_response = false;
+ push_body = complete_response;
+ }
+ vector[0].buf = (char *) header;
+ vector[0].len = (unsigned long) header_size;
+ vector[1].buf = (char *) body;
+ vector[1].len = (unsigned long) body_size;
+
+ ret = WSASend (s, vector, 2, &vec_sent, 0, NULL, NULL);
+ if (0 == ret)
+ ret = (ssize_t) vec_sent;
+ else
+ ret = -1;
+#endif /* _WIN32 */
+
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#if EPOLL_SUPPORT
+ /* EAGAIN, no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
+ return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EPIPE_))
+ return MHD_ERR_PIPE_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EOPNOTSUPP_))
+ return MHD_ERR_OPNOTSUPP_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ENOTCONN_))
+ return MHD_ERR_NOTCONN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EINVAL_))
+ return MHD_ERR_INVAL_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* Treat any other error as a hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+#if EPOLL_SUPPORT
+ else if ((header_size + body_size) > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+
+ /* If there is a need to push the data from network buffers
+ * call post_send_setopt(). */
+ if ( (push_body) &&
+ ((header_size + body_size) == (size_t) ret) )
+ {
+ /* Complete reply has been sent. */
+ /* If TLS connection is used then next final send() will be
+ * without MSG_MORE support. If non-TLS connection is used
+ * it's unknown whether next 'send' will be plain send() / sendmsg() or
+ * sendfile() will be used so assume that next final send() will be
+ * the same, like for this response. */
+ post_send_setopt (connection,
+#ifdef HAVE_SENDMSG
+ true,
+#else /* ! HAVE_SENDMSG */
+ false,
+#endif /* ! HAVE_SENDMSG */
+ true);
+ }
+ else if ( (push_hdr) &&
+ (header_size <= (size_t) ret))
+ {
+ /* The header has been sent completely and there is a
+ * need to push the header data. */
+ /* Luckily the type of send function will be used next is known. */
+ post_send_setopt (connection,
+#if defined(_MHD_HAVE_SENDFILE)
+ MHD_resp_sender_std == connection->resp_sender,
+#else /* ! _MHD_HAVE_SENDFILE */
+ true,
+#endif /* ! _MHD_HAVE_SENDFILE */
+ true);
+ }
+
+ return ret;
+#else /* ! MHD_VECT_SEND */
+ mhd_assert (false);
+ return MHD_ERR_CONNRESET_; /* Unreachable. Mute warnings. */
+#endif /* ! MHD_VECT_SEND */
+}
+
+
+#if defined(_MHD_HAVE_SENDFILE)
+ssize_t
+MHD_send_sendfile_ (struct MHD_Connection *connection)
+{
+ ssize_t ret;
+ const int file_fd = connection->response->fd;
+ uint64_t left;
+ uint64_t offsetu64;
+#ifndef HAVE_SENDFILE64
+ const uint64_t max_off_t = (uint64_t) OFF_T_MAX;
+#else /* HAVE_SENDFILE64 */
+ const uint64_t max_off_t = (uint64_t) OFF64_T_MAX;
+#endif /* HAVE_SENDFILE64 */
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#ifndef HAVE_SENDFILE64
+ off_t offset;
+#else /* HAVE_SENDFILE64 */
+ off64_t offset;
+#endif /* HAVE_SENDFILE64 */
+#endif /* MHD_LINUX_SOLARIS_SENDFILE */
+#ifdef HAVE_FREEBSD_SENDFILE
+ off_t sent_bytes;
+ int flags = 0;
+#endif
+#ifdef HAVE_DARWIN_SENDFILE
+ off_t len;
+#endif /* HAVE_DARWIN_SENDFILE */
+ const bool used_thr_p_c = (0 != (connection->daemon->options
+ & MHD_USE_THREAD_PER_CONNECTION));
+ const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ :
+ MHD_SENFILE_CHUNK_;
+ size_t send_size = 0;
+ bool push_data;
+ mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
+ mhd_assert (0 == (connection->daemon->options & MHD_USE_TLS));
+
+ offsetu64 = connection->response_write_position
+ + connection->response->fd_off;
+ if (max_off_t < offsetu64)
+ { /* Retry to send with standard 'send()'. */
+ connection->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+
+ left = connection->response->total_size - connection->response_write_position;
+
+ if ( (uint64_t) SSIZE_MAX < left)
+ left = SSIZE_MAX;
+
+ /* Do not allow system to stick sending on single fast connection:
+ * use 128KiB chunks (2MiB for thread-per-connection). */
+ if (chunk_size < left)
+ {
+ send_size = chunk_size;
+ push_data = false; /* No need to push data, there is more to send. */
+ }
+ else
+ {
+ send_size = (size_t) left;
+ push_data = true; /* Final piece of data, need to push to the network. */
+ }
+ pre_send_setopt (connection, false, push_data);
+
+#ifdef MHD_LINUX_SOLARIS_SENDFILE
+#ifndef HAVE_SENDFILE64
+ offset = (off_t) offsetu64;
+ ret = sendfile (connection->socket_fd,
+ file_fd,
+ &offset,
+ send_size);
+#else /* HAVE_SENDFILE64 */
+ offset = (off64_t) offsetu64;
+ ret = sendfile64 (connection->socket_fd,
+ file_fd,
+ &offset,
+ send_size);
+#endif /* HAVE_SENDFILE64 */
+ if (0 > ret)
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* EAGAIN --- no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+#ifdef HAVE_LINUX_SENDFILE
+ if (MHD_SCKT_ERR_IS_ (err,
+ MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* sendfile() failed with EINVAL if mmap()-like operations are not
+ supported for FD or other 'unusual' errors occurred, so we should try
+ to fall back to 'SEND'; see also this thread for info on
+ odd libc/Linux behavior with sendfile:
+ http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
+ connection->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+#else /* HAVE_SOLARIS_SENDFILE */
+ if ( (EAFNOSUPPORT == err) ||
+ (EINVAL == err) ||
+ (EOPNOTSUPP == err) )
+ { /* Retry with standard file reader. */
+ connection->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ if ( (ENOTCONN == err) ||
+ (EPIPE == err) )
+ {
+ return MHD_ERR_CONNRESET_;
+ }
+ return MHD_ERR_BADF_; /* Fail hard */
+#endif /* HAVE_SOLARIS_SENDFILE */
+ }
+#ifdef EPOLL_SUPPORT
+ else if (send_size > (size_t) ret)
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+#elif defined(HAVE_FREEBSD_SENDFILE)
+#ifdef SF_FLAGS
+ flags = used_thr_p_c ?
+ freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
+#endif /* SF_FLAGS */
+ if (0 != sendfile (file_fd,
+ connection->socket_fd,
+ (off_t) offsetu64,
+ send_size,
+ NULL,
+ &sent_bytes,
+ flags))
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
+ MHD_SCKT_ERR_IS_EINTR_ (err) ||
+ (EBUSY == err) )
+ {
+ mhd_assert (SSIZE_MAX >= sent_bytes);
+ if (0 != sent_bytes)
+ return (ssize_t) sent_bytes;
+
+ return MHD_ERR_AGAIN_;
+ }
+ /* Some unrecoverable error. Possibly file FD is not suitable
+ * for sendfile(). Retry with standard send(). */
+ connection->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ mhd_assert (0 < sent_bytes);
+ mhd_assert (SSIZE_MAX >= sent_bytes);
+ ret = (ssize_t) sent_bytes;
+#elif defined(HAVE_DARWIN_SENDFILE)
+ len = (off_t) send_size; /* chunk always fit */
+ if (0 != sendfile (file_fd,
+ connection->socket_fd,
+ (off_t) offsetu64,
+ &len,
+ NULL,
+ 0))
+ {
+ const int err = MHD_socket_get_error_ ();
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
+ MHD_SCKT_ERR_IS_EINTR_ (err))
+ {
+ mhd_assert (0 <= len);
+ mhd_assert (SSIZE_MAX >= len);
+ mhd_assert (send_size >= (size_t) len);
+ if (0 != len)
+ return (ssize_t) len;
+
+ return MHD_ERR_AGAIN_;
+ }
+ if ((ENOTCONN == err) ||
+ (EPIPE == err) )
+ return MHD_ERR_CONNRESET_;
+ if ((ENOTSUP == err) ||
+ (EOPNOTSUPP == err) )
+ { /* This file FD is not suitable for sendfile().
+ * Retry with standard send(). */
+ connection->resp_sender = MHD_resp_sender_std;
+ return MHD_ERR_AGAIN_;
+ }
+ return MHD_ERR_BADF_; /* Return hard error. */
+ }
+ mhd_assert (0 <= len);
+ mhd_assert (SSIZE_MAX >= len);
+ mhd_assert (send_size >= (size_t) len);
+ ret = (ssize_t) len;
+#endif /* HAVE_FREEBSD_SENDFILE */
+
+ /* If there is a need to push the data from network buffers
+ * call post_send_setopt(). */
+ /* It's unknown whether sendfile() will be used in the next
+ * response so assume that next response will be the same. */
+ if ( (push_data) &&
+ (send_size == (size_t) ret) )
+ post_send_setopt (connection, false, push_data);
+
+ return ret;
+}
+
+
+#endif /* _MHD_HAVE_SENDFILE */
+
+#if defined(MHD_VECT_SEND)
+
+
+/**
+ * Function sends iov data by system sendmsg or writev function.
+ *
+ * Connection must be in non-TLS (non-HTTPS) mode.
+ *
+ * @param connection the MHD connection structure
+ * @param r_iov the pointer to iov data structure with tracking
+ * @param push_data set to true to force push the data to the network from
+ * system buffers (usually set for the last piece of data),
+ * set to false to prefer holding incomplete network packets
+ * (more data will be send for the same reply).
+ * @return actual number of bytes sent
+ */
+static ssize_t
+send_iov_nontls (struct MHD_Connection *connection,
+ struct MHD_iovec_track_ *const r_iov,
+ bool push_data)
+{
+ ssize_t res;
+ ssize_t total_sent;
+ size_t items_to_send;
+#ifdef HAVE_SENDMSG
+ struct msghdr msg;
+#elif defined(MHD_WINSOCK_SOCKETS)
+ DWORD bytes_sent;
+ DWORD cnt_w;
+#endif /* MHD_WINSOCK_SOCKETS */
+
+ mhd_assert (0 == (connection->daemon->options & MHD_USE_TLS));
+
+ if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
+ (MHD_CONNECTION_CLOSED == connection->state) )
+ {
+ return MHD_ERR_NOTCONN_;
+ }
+
+ items_to_send = r_iov->cnt - r_iov->sent;
+#ifdef _MHD_IOV_MAX
+ if (_MHD_IOV_MAX < items_to_send)
+ {
+ mhd_assert (0 < _MHD_IOV_MAX);
+ if (0 == _MHD_IOV_MAX)
+ return MHD_ERR_NOTCONN_; /* Should never happen */
+ items_to_send = _MHD_IOV_MAX;
+ push_data = false; /* Incomplete response */
+ }
+#endif /* _MHD_IOV_MAX */
+#ifdef HAVE_SENDMSG
+ memset (&msg, 0, sizeof(struct msghdr));
+ msg.msg_iov = r_iov->iov + r_iov->sent;
+ msg.msg_iovlen = items_to_send;
+
+ pre_send_setopt (connection, true, push_data);
+#ifdef MHD_USE_MSG_MORE
+ res = sendmsg (connection->socket_fd, &msg,
+ MSG_NOSIGNAL_OR_ZERO | (push_data ? 0 : MSG_MORE));
+#else /* ! MHD_USE_MSG_MORE */
+ res = sendmsg (connection->socket_fd, &msg, MSG_NOSIGNAL_OR_ZERO);
+#endif /* ! MHD_USE_MSG_MORE */
+#elif defined(HAVE_WRITEV)
+ pre_send_setopt (connection, true, push_data);
+ res = writev (connection->socket_fd, r_iov->iov + r_iov->sent,
+ items_to_send);
+#elif defined(MHD_WINSOCK_SOCKETS)
+#ifdef _WIN64
+ if (items_to_send > UINT32_MAX)
+ {
+ cnt_w = UINT32_MAX;
+ push_data = false; /* Incomplete response */
+ }
+ else
+ cnt_w = (DWORD) items_to_send;
+#else /* ! _WIN64 */
+ cnt_w = (DWORD) items_to_send;
+#endif /* ! _WIN64 */
+ pre_send_setopt (connection, true, push_data);
+ if (0 == WSASend (connection->socket_fd,
+ (LPWSABUF) (r_iov->iov + r_iov->sent),
+ cnt_w,
+ &bytes_sent, 0, NULL, NULL))
+ res = (ssize_t) bytes_sent;
+ else
+ res = -1;
+#else /* !HAVE_SENDMSG && !HAVE_WRITEV && !MHD_WINSOCK_SOCKETS */
+#error No vector-send function available
+#endif
+
+ if (0 > res)
+ {
+ const int err = MHD_socket_get_error_ ();
+
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
+ {
+#ifdef EPOLL_SUPPORT
+ /* EAGAIN --- no longer write-ready */
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ return MHD_ERR_AGAIN_;
+ }
+ if (MHD_SCKT_ERR_IS_EINTR_ (err))
+ return MHD_ERR_AGAIN_;
+ if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
+ return MHD_ERR_CONNRESET_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EPIPE_))
+ return MHD_ERR_PIPE_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EOPNOTSUPP_))
+ return MHD_ERR_OPNOTSUPP_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ENOTCONN_))
+ return MHD_ERR_NOTCONN_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EINVAL_))
+ return MHD_ERR_INVAL_;
+ if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))
+ return MHD_ERR_NOMEM_;
+ if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EBADF_))
+ return MHD_ERR_BADF_;
+ /* Treat any other error as a hard error. */
+ return MHD_ERR_NOTCONN_;
+ }
+
+ /* Some data has been sent */
+ total_sent = res;
+ /* Adjust the internal tracking information for the iovec to
+ * take this last send into account. */
+ while ((0 != res) && (r_iov->iov[r_iov->sent].iov_len <= (size_t) res))
+ {
+ res -= r_iov->iov[r_iov->sent].iov_len;
+ r_iov->sent++; /* The iov element has been completely sent */
+ mhd_assert ((r_iov->cnt > r_iov->sent) || (0 == res));
+ }
+
+ if (r_iov->cnt == r_iov->sent)
+ post_send_setopt (connection, true, push_data);
+ else
+ {
+#ifdef EPOLL_SUPPORT
+ connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
+#endif /* EPOLL_SUPPORT */
+ if (0 != res)
+ {
+ mhd_assert (r_iov->cnt > r_iov->sent);
+ /* The last iov element has been partially sent */
+ r_iov->iov[r_iov->sent].iov_base =
+ (void*) ((uint8_t*) r_iov->iov[r_iov->sent].iov_base + (size_t) res);
+ r_iov->iov[r_iov->sent].iov_len -= (MHD_iov_size_) res;
+ }
+ }
+
+ return total_sent;
+}
+
+
+#endif /* MHD_VECT_SEND */
+
+#if ! defined(MHD_VECT_SEND) || defined(HTTPS_SUPPORT) || \
+ defined(_MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED)
+
+
+/**
+ * Function sends iov data by sending buffers one-by-one by standard
+ * data send function.
+ *
+ * Connection could be in HTTPS or non-HTTPS mode.
+ *
+ * @param connection the MHD connection structure
+ * @param r_iov the pointer to iov data structure with tracking
+ * @param push_data set to true to force push the data to the network from
+ * system buffers (usually set for the last piece of data),
+ * set to false to prefer holding incomplete network packets
+ * (more data will be send for the same reply).
+ * @return actual number of bytes sent
+ */
+static ssize_t
+send_iov_emu (struct MHD_Connection *connection,
+ struct MHD_iovec_track_ *const r_iov,
+ bool push_data)
+{
+ const bool non_blk = connection->sk_nonblck;
+ size_t total_sent;
+ ssize_t res;
+
+ mhd_assert (NULL != r_iov->iov);
+ total_sent = 0;
+ do
+ {
+ if ((size_t) SSIZE_MAX - total_sent < r_iov->iov[r_iov->sent].iov_len)
+ return total_sent; /* return value would overflow */
+
+ res = MHD_send_data_ (connection,
+ r_iov->iov[r_iov->sent].iov_base,
+ r_iov->iov[r_iov->sent].iov_len,
+ push_data && (r_iov->cnt == r_iov->sent + 1));
+ if (0 > res)
+ {
+ /* Result is an error */
+ if (0 == total_sent)
+ return res; /* Nothing was sent, return result as is */
+
+ if (MHD_ERR_AGAIN_ == res)
+ return total_sent; /* Some data has been sent, return the amount */
+
+ return res; /* Any kind of a hard error */
+ }
+
+ total_sent += (size_t) res;
+
+ if (r_iov->iov[r_iov->sent].iov_len != (size_t) res)
+ {
+ /* Incomplete buffer has been sent.
+ * Adjust buffer of the last element. */
+ r_iov->iov[r_iov->sent].iov_base =
+ (void*) ((uint8_t*) r_iov->iov[r_iov->sent].iov_base + (size_t) res);
+ r_iov->iov[r_iov->sent].iov_len -= res;
+
+ return total_sent;
+ }
+ /* The iov element has been completely sent */
+ r_iov->sent++;
+ } while ((r_iov->cnt > r_iov->sent) && (non_blk));
+
+ return (ssize_t) total_sent;
+}
+
+
+#endif /* !MHD_VECT_SEND || HTTPS_SUPPORT
+ || _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED */
+
+
+ssize_t
+MHD_send_iovec_ (struct MHD_Connection *connection,
+ struct MHD_iovec_track_ *const r_iov,
+ bool push_data)
+{
+#ifdef MHD_VECT_SEND
+#if defined(HTTPS_SUPPORT) || \
+ defined(_MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED)
+ bool use_iov_send = true;
+#endif /* HTTPS_SUPPORT || _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED */
+#endif /* MHD_VECT_SEND */
+
+ mhd_assert (NULL != connection->resp_iov.iov);
+ mhd_assert (NULL != connection->response->data_iov);
+ mhd_assert (connection->resp_iov.cnt > connection->resp_iov.sent);
+#ifdef MHD_VECT_SEND
+#if defined(HTTPS_SUPPORT) || \
+ defined(_MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED)
+#ifdef HTTPS_SUPPORT
+ use_iov_send = use_iov_send &&
+ (0 == (connection->daemon->options & MHD_USE_TLS));
+#endif /* HTTPS_SUPPORT */
+#ifdef _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED
+ use_iov_send = use_iov_send && (connection->daemon->sigpipe_blocked ||
+ connection->sk_spipe_suppress);
+#endif /* _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED */
+ if (use_iov_send)
+#endif /* HTTPS_SUPPORT || _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED */
+ return send_iov_nontls (connection, r_iov, push_data);
+#endif /* MHD_VECT_SEND */
+
+#if ! defined(MHD_VECT_SEND) || defined(HTTPS_SUPPORT) || \
+ defined(_MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED)
+ return send_iov_emu (connection, r_iov, push_data);
+#endif /* !MHD_VECT_SEND || HTTPS_SUPPORT
+ || _MHD_VECT_SEND_NEEDS_SPIPE_SUPPRESSED */
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_send.h
^
|
@@ -0,0 +1,163 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2017, 2020 Karlson2k (Evgeny Grin)
+ Copyright (C) 2019 ng0
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+/**
+ * @file mhd_send.h
+ * @brief Declarations of send() wrappers.
+ * @author ng0
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_SEND_H
+#define MHD_SEND_H
+
+#include "platform.h"
+#include "internal.h"
+#if defined(HAVE_STDBOOL_H)
+#include <stdbool.h>
+#endif /* HAVE_STDBOOL_H */
+#include <errno.h>
+#include "mhd_sockets.h"
+#include "connection.h"
+#ifdef HTTPS_SUPPORT
+#include "connection_https.h"
+#endif
+
+#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) || \
+ defined(MHD_WINSOCK_SOCKETS)
+#define MHD_VECT_SEND 1
+#endif /* HAVE_SENDMSG || HAVE_WRITEV || MHD_WINSOCK_SOCKETS */
+
+/**
+ * Initialises static variables
+ */
+void
+MHD_send_init_static_vars_ (void);
+
+
+/**
+ * Send buffer to the client, push data from network buffer if requested
+ * and full buffer is sent.
+ *
+ * @param connection the MHD_Connection structure
+ * @param buffer content of the buffer to send
+ * @param buffer_size the size of the @a buffer (in bytes)
+ * @param push_data set to true to force push the data to the network from
+ * system buffers (usually set for the last piece of data),
+ * set to false to prefer holding incomplete network packets
+ * (more data will be send for the same reply).
+ * @return sum of the number of bytes sent from both buffers or
+ * error code (negative)
+ */
+ssize_t
+MHD_send_data_ (struct MHD_Connection *connection,
+ const char *buffer,
+ size_t buffer_size,
+ bool push_data);
+
+
+/**
+ * Send reply header with optional reply body.
+ *
+ * @param connection the MHD_Connection structure
+ * @param header content of header to send
+ * @param header_size the size of the @a header (in bytes)
+ * @param never_push_hdr set to true to disable internal algorithm
+ * that can push automatically header data
+ * alone to the network
+ * @param body content of the body to send (optional, may be NULL)
+ * @param body_size the size of the @a body (in bytes)
+ * @param complete_response set to true if complete response
+ * is provided by @a header and @a body,
+ * set to false if additional body data
+ * will be sent later
+ * @return sum of the number of bytes sent from both buffers or
+ * error code (negative)
+ */
+ssize_t
+MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
+ const char *header,
+ size_t header_size,
+ bool never_push_hdr,
+ const char *body,
+ size_t body_size,
+ bool complete_response);
+
+#if defined(_MHD_HAVE_SENDFILE)
+/**
+ * Function for sending responses backed by file FD.
+ *
+ * @param connection the MHD connection structure
+ * @return actual number of bytes sent
+ */
+ssize_t
+MHD_send_sendfile_ (struct MHD_Connection *connection);
+
+#endif
+
+
+/**
+ * Set required TCP_NODELAY state for connection socket
+ *
+ * The function automatically updates sk_nodelay state.
+ * @param connection the connection to manipulate
+ * @param nodelay_state the requested new state of socket
+ * @return true if succeed, false if failed or not supported
+ * by the current platform / kernel.
+ */
+bool
+MHD_connection_set_nodelay_state_ (struct MHD_Connection *connection,
+ bool nodelay_state);
+
+
+/**
+ * Set required cork state for connection socket
+ *
+ * The function automatically updates sk_corked state.
+ *
+ * @param connection the connection to manipulate
+ * @param cork_state the requested new state of socket
+ * @return true if succeed, false if failed or not supported
+ * by the current platform / kernel.
+ */
+bool
+MHD_connection_set_cork_state_ (struct MHD_Connection *connection,
+ bool cork_state);
+
+
+/**
+ * Function for sending responses backed by a an array of memory buffers.
+ *
+ * @param connection the MHD connection structure
+ * @param r_iov the pointer to iov response structure with tracking
+ * @param push_data set to true to force push the data to the network from
+ * system buffers (usually set for the last piece of data),
+ * set to false to prefer holding incomplete network packets
+ * (more data will be send for the same reply).
+ * @return actual number of bytes sent
+ */
+ssize_t
+MHD_send_iovec_ (struct MHD_Connection *connection,
+ struct MHD_iovec_track_ *const r_iov,
+ bool push_data);
+
+
+#endif /* MHD_SEND_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_sockets.c
^
|
@@ -17,18 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
/**
* @file microhttpd/mhd_sockets.c
* @brief Implementation for sockets functions
* @author Karlson2k (Evgeny Grin)
*/
-
#include "mhd_sockets.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#include <fcntl.h>
#ifdef MHD_WINSOCK_SOCKETS
@@ -37,10 +31,11 @@
* @param err the WinSock error code.
* @return pointer to string description of specified WinSock error.
*/
-const char* MHD_W32_strerror_winsock_(int err)
+const char*
+MHD_W32_strerror_winsock_ (int err)
{
switch (err)
- {
+ {
case 0:
return "No error";
case WSA_INVALID_HANDLE:
@@ -233,7 +228,7 @@
return "Invalid QoS shaping rate object";
case WSA_QOS_RESERVED_PETYPE:
return "Reserved policy QoS element type";
- }
+ }
return "Unknown winsock error";
}
@@ -246,117 +241,119 @@
* @return non-zero if succeeded, zero otherwise
*/
int
-MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk)
+MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk)
{
int i;
if (! sockets_pair)
- {
- WSASetLastError (WSAEFAULT);
- return 0;
- }
+ {
+ WSASetLastError (WSAEFAULT);
+ return 0;
+ }
#define PAIRMAXTRYIES 800
for (i = 0; i < PAIRMAXTRYIES; i++)
+ {
+ struct sockaddr_in listen_addr;
+ SOCKET listen_s;
+ static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
+ int addr_len = c_addinlen;
+ unsigned long on_val = 1;
+ unsigned long off_val = 0;
+
+ listen_s = socket (AF_INET,
+ SOCK_STREAM,
+ IPPROTO_TCP);
+ if (INVALID_SOCKET == listen_s)
+ break; /* can't create even single socket */
+
+ listen_addr.sin_family = AF_INET;
+ listen_addr.sin_port = 0; /* same as htons(0) */
+ listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if ( ((0 == bind (listen_s,
+ (struct sockaddr*) &listen_addr,
+ c_addinlen)) &&
+ (0 == listen (listen_s,
+ 1) ) &&
+ (0 == getsockname (listen_s,
+ (struct sockaddr*) &listen_addr,
+ &addr_len))) )
{
- struct sockaddr_in listen_addr;
- SOCKET listen_s;
- static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
- int addr_len = c_addinlen;
- unsigned long on_val = 1;
- unsigned long off_val = 0;
-
- listen_s = socket (AF_INET,
- SOCK_STREAM,
- IPPROTO_TCP);
- if (INVALID_SOCKET == listen_s)
- break; /* can't create even single socket */
-
- listen_addr.sin_family = AF_INET;
- listen_addr.sin_port = 0; /* same as htons(0) */
- listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- if ( (0 == bind (listen_s,
- (struct sockaddr*) &listen_addr,
- c_addinlen) &&
- (0 == listen (listen_s,
- 1) ) &&
- (0 == getsockname (listen_s,
- (struct sockaddr*) &listen_addr,
- &addr_len))) )
- {
- SOCKET client_s = socket(AF_INET,
- SOCK_STREAM,
- IPPROTO_TCP);
- struct sockaddr_in accepted_from_addr;
- struct sockaddr_in client_addr;
- SOCKET server_s;
-
- if (INVALID_SOCKET == client_s)
- {
- /* try again */
- closesocket (listen_s);
- continue;
- }
-
- if ( (0 != ioctlsocket (client_s,
- FIONBIO,
- &on_val)) ||
- ( (0 != connect (client_s,
- (struct sockaddr*) &listen_addr,
- c_addinlen)) &&
- (WSAGetLastError() != WSAEWOULDBLOCK)) )
- {
- /* try again */
- closesocket (listen_s);
- closesocket (client_s);
- continue;
- }
-
- addr_len = c_addinlen;
- server_s = accept (listen_s,
- (struct sockaddr*) &accepted_from_addr,
- &addr_len);
- if (INVALID_SOCKET == server_s)
- {
- /* try again */
- closesocket (listen_s);
- closesocket (client_s);
- continue;
- }
-
- addr_len = c_addinlen;
- if ( (0 == getsockname (client_s,
- (struct sockaddr*) &client_addr,
- &addr_len)) &&
- (accepted_from_addr.sin_family == client_addr.sin_family) &&
- (accepted_from_addr.sin_port == client_addr.sin_port) &&
- (accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr) &&
- ( (0 != non_blk) ?
- (0 == ioctlsocket(server_s,
- FIONBIO,
- &on_val)) :
- (0 == ioctlsocket(client_s,
- FIONBIO,
- &off_val)) ) )
- {
- closesocket (listen_s);
- sockets_pair[0] = server_s;
- sockets_pair[1] = client_s;
- return !0;
- }
- closesocket (server_s);
- closesocket (client_s);
- }
- closesocket(listen_s);
+ SOCKET client_s = socket (AF_INET,
+ SOCK_STREAM,
+ IPPROTO_TCP);
+ struct sockaddr_in accepted_from_addr;
+ struct sockaddr_in client_addr;
+ SOCKET server_s;
+
+ if (INVALID_SOCKET == client_s)
+ {
+ /* try again */
+ closesocket (listen_s);
+ continue;
+ }
+
+ if ( (0 != ioctlsocket (client_s,
+ FIONBIO,
+ &on_val)) ||
+ ( (0 != connect (client_s,
+ (struct sockaddr*) &listen_addr,
+ c_addinlen)) &&
+ (WSAGetLastError () != WSAEWOULDBLOCK)) )
+ {
+ /* try again */
+ closesocket (listen_s);
+ closesocket (client_s);
+ continue;
+ }
+
+ addr_len = c_addinlen;
+ server_s = accept (listen_s,
+ (struct sockaddr*) &accepted_from_addr,
+ &addr_len);
+ if (INVALID_SOCKET == server_s)
+ {
+ /* try again */
+ closesocket (listen_s);
+ closesocket (client_s);
+ continue;
+ }
+
+ addr_len = c_addinlen;
+ if ( (0 == getsockname (client_s,
+ (struct sockaddr*) &client_addr,
+ &addr_len)) &&
+ (accepted_from_addr.sin_family == client_addr.sin_family) &&
+ (accepted_from_addr.sin_port == client_addr.sin_port) &&
+ (accepted_from_addr.sin_addr.s_addr ==
+ client_addr.sin_addr.s_addr) &&
+ ( (0 != non_blk) ?
+ (0 == ioctlsocket (server_s,
+ FIONBIO,
+ &on_val)) :
+ (0 == ioctlsocket (client_s,
+ FIONBIO,
+ &off_val)) ) )
+ {
+ closesocket (listen_s);
+ sockets_pair[0] = server_s;
+ sockets_pair[1] = client_s;
+ return ! 0;
+ }
+ closesocket (server_s);
+ closesocket (client_s);
}
+ closesocket (listen_s);
+ }
sockets_pair[0] = INVALID_SOCKET;
sockets_pair[1] = INVALID_SOCKET;
- WSASetLastError(WSAECONNREFUSED);
+ WSASetLastError (WSAECONNREFUSED);
return 0;
}
+
#endif /* MHD_WINSOCK_SOCKETS */
@@ -383,9 +380,9 @@
set,
fd_setsize))
return 0;
- MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,
- set,
- fd_setsize);
+ MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_ (fd,
+ set,
+ fd_setsize);
if ( (NULL != max_fd) &&
( (fd > *max_fd) ||
(MHD_INVALID_SOCKET == *max_fd) ) )
@@ -424,7 +421,7 @@
&flags))
return 0;
#endif /* MHD_WINSOCK_SOCKETS */
- return !0;
+ return ! 0;
}
@@ -452,70 +449,112 @@
flags | FD_CLOEXEC)) )
return 0;
#elif defined(MHD_WINSOCK_SOCKETS)
- if (! SetHandleInformation ((HANDLE)sock,
+ if (! SetHandleInformation ((HANDLE) sock,
HANDLE_FLAG_INHERIT,
0))
return 0;
#endif /* MHD_WINSOCK_SOCKETS */
- return !0;
+ return ! 0;
+}
+
+
+/**
+ * Disable Nagle's algorithm on @a sock. This is what we do by default for
+ * all TCP sockets in MHD, unless the platform does not support the MSG_MORE
+ * or MSG_CORK or MSG_NOPUSH options.
+ *
+ * @param sock socket to manipulate
+ * @param on value to use
+ * @return 0 on success
+ */
+int
+MHD_socket_set_nodelay_ (MHD_socket sock,
+ bool on)
+{
+#ifdef TCP_NODELAY
+ {
+ const MHD_SCKT_OPT_BOOL_ off_val = 0;
+ const MHD_SCKT_OPT_BOOL_ on_val = 1;
+ /* Disable Nagle's algorithm for normal buffering */
+ return setsockopt (sock,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const void *) ((on) ? &on_val : &off_val),
+ sizeof (on_val));
+ }
+#else
+ (void) sock;
+ return 0;
+#endif /* TCP_NODELAY */
}
/**
* Create a listen socket, with noninheritable flag if possible.
*
- * @param use_ipv6 if set to non-zero IPv6 is used
+ * @param pf protocol family to use
* @return created socket or MHD_INVALID_SOCKET in case of errors
*/
MHD_socket
-MHD_socket_create_listen_ (int use_ipv6)
+MHD_socket_create_listen_ (int pf)
{
- int domain;
MHD_socket fd;
int cloexec_set;
-
-#ifdef HAVE_INET6
- domain = (use_ipv6) ? PF_INET6 : PF_INET;
-#else /* ! HAVE_INET6 */
- if (use_ipv6)
- return MHD_INVALID_SOCKET;
- domain = PF_INET;
-#endif /* ! HAVE_INET6 */
-
-#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC)
- fd = socket (domain,
- SOCK_STREAM | SOCK_CLOEXEC,
+#if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
+ int nosigpipe_set;
+#endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
+
+#if defined(MHD_POSIX_SOCKETS) && (defined(SOCK_CLOEXEC) || \
+ defined(SOCK_NOSIGPIPE) )
+ fd = socket (pf,
+ SOCK_STREAM | SOCK_CLOEXEC | SOCK_NOSIGPIPE_OR_ZERO,
0);
- cloexec_set = !0;
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ cloexec_set = (SOCK_CLOEXEC_OR_ZERO != 0);
+#if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
+ nosigpipe_set = (SOCK_NOSIGPIPE_OR_ZERO != 0);
+#endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
+ }
#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
- fd = WSASocketW (domain,
+ fd = WSASocketW (pf,
SOCK_STREAM,
0,
NULL,
0,
- WSA_FLAG_NO_HANDLE_INHERIT);
- cloexec_set = !0;
+ WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
+ cloexec_set = ! 0;
#else /* !SOCK_CLOEXEC */
fd = MHD_INVALID_SOCKET;
#endif /* !SOCK_CLOEXEC */
if (MHD_INVALID_SOCKET == fd)
- {
- fd = socket (domain,
- SOCK_STREAM,
- 0);
- cloexec_set = 0;
- }
+ {
+ fd = socket (pf,
+ SOCK_STREAM,
+ 0);
+ cloexec_set = 0;
+#if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
+ nosigpipe_set = 0;
+#endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
+ }
if (MHD_INVALID_SOCKET == fd)
return MHD_INVALID_SOCKET;
-#ifdef MHD_socket_nosignal_
- if(! MHD_socket_nosignal_(fd))
- {
- const int err = MHD_socket_get_error_ ();
- (void) MHD_socket_close_ (fd);
- MHD_socket_fset_error_ (err);
- return MHD_INVALID_SOCKET;
- }
-#endif /* MHD_socket_nosignal_ */
+
+#if defined(MHD_socket_nosignal_)
+ if ( (! nosigpipe_set) &&
+ (0 == MHD_socket_nosignal_ (fd)) &&
+ (0 == MSG_NOSIGNAL_OR_ZERO) )
+ {
+ /* SIGPIPE disable is possible on this platform
+ * (so application expect that it will be disabled),
+ * but failed to be disabled here and it is not
+ * possible to disable SIGPIPE by MSG_NOSIGNAL. */
+ const int err = MHD_socket_get_error_ ();
+ (void) MHD_socket_close_ (fd);
+ MHD_socket_fset_error_ (err);
+ return MHD_INVALID_SOCKET;
+ }
+#endif /* defined(MHD_socket_nosignal_) */
if (! cloexec_set)
(void) MHD_socket_noninheritable_ (fd);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_sockets.h
^
|
@@ -35,9 +35,14 @@
#include "mhd_options.h"
#include <errno.h>
+#include <stdbool.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
-#if !defined(MHD_POSIX_SOCKETS) && !defined(MHD_WINSOCK_SOCKETS)
-# if !defined(_WIN32) || defined(__CYGWIN__)
+#if ! defined(MHD_POSIX_SOCKETS) && ! defined(MHD_WINSOCK_SOCKETS)
+# if ! defined(_WIN32) || defined(__CYGWIN__)
# define MHD_POSIX_SOCKETS 1
# else /* defined(_WIN32) && !defined(__CYGWIN__) */
# define MHD_WINSOCK_SOCKETS 1
@@ -92,7 +97,7 @@
# include <sys/epoll.h>
# endif
# ifdef HAVE_NETINET_TCP_H
- /* for TCP_FASTOPEN and TCP_CORK */
+/* for TCP_FASTOPEN and TCP_CORK */
# include <netinet/tcp.h>
# endif
# ifdef HAVE_STRING_H
@@ -111,19 +116,23 @@
#endif
#include <stddef.h>
-#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
+#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
# include <stdint.h>
# define _SSIZE_T_DEFINED
- typedef intptr_t ssize_t;
+typedef intptr_t ssize_t;
#endif /* !_SSIZE_T_DEFINED */
+#ifdef __FreeBSD__
+#include <sys/param.h> /* For __FreeBSD_version */
+#endif /* __FreeBSD__ */
+
#include "mhd_limits.h"
#ifdef _MHD_FD_SETSIZE_IS_DEFAULT
# define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE
#else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
# include "sysfdsetsize.h"
-# define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value()
+# define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value ()
#endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
#ifndef MHD_PANIC
@@ -131,8 +140,9 @@
# include <stdlib.h>
/* Simple implementation of MHD_PANIC, to be used outside lib */
# define MHD_PANIC(msg) do { fprintf (stderr, \
- "Abnormal termination at %d line in file %s: %s\n", \
- (int)__LINE__, __FILE__, msg); abort();} while(0)
+ "Abnormal termination at %d line in file %s: %s\n", \
+ (int) __LINE__, __FILE__, msg); abort (); \
+} while (0)
#endif /* ! MHD_PANIC */
#ifndef MHD_SOCKET_DEFINED
@@ -140,10 +150,10 @@
* MHD_socket is type for socket FDs
*/
# if defined(MHD_POSIX_SOCKETS)
- typedef int MHD_socket;
+typedef int MHD_socket;
# define MHD_INVALID_SOCKET (-1)
# elif defined(MHD_WINSOCK_SOCKETS)
- typedef SOCKET MHD_socket;
+typedef SOCKET MHD_socket;
# define MHD_INVALID_SOCKET (INVALID_SOCKET)
# endif /* MHD_WINSOCK_SOCKETS */
@@ -151,34 +161,41 @@
#endif /* ! MHD_SOCKET_DEFINED */
#ifdef SOCK_CLOEXEC
-# define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC
+# define SOCK_CLOEXEC_OR_ZERO SOCK_CLOEXEC
#else /* ! SOCK_CLOEXEC */
-# define MAYBE_SOCK_CLOEXEC 0
+# define SOCK_CLOEXEC_OR_ZERO 0
#endif /* ! SOCK_CLOEXEC */
#ifdef HAVE_SOCK_NONBLOCK
-# define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK
+# define SOCK_NONBLOCK_OR_ZERO SOCK_NONBLOCK
+#else /* ! HAVE_SOCK_NONBLOCK */
+# define SOCK_NONBLOCK_OR_ZERO 0
+#endif /* ! HAVE_SOCK_NONBLOCK */
+
+#ifdef SOCK_NOSIGPIPE
+# define SOCK_NOSIGPIPE_OR_ZERO SOCK_NOSIGPIPE
#else /* ! HAVE_SOCK_NONBLOCK */
-# define MAYBE_SOCK_NONBLOCK 0
+# define SOCK_NOSIGPIPE_OR_ZERO 0
#endif /* ! HAVE_SOCK_NONBLOCK */
#ifdef MSG_NOSIGNAL
-# define MAYBE_MSG_NOSIGNAL MSG_NOSIGNAL
+# define MSG_NOSIGNAL_OR_ZERO MSG_NOSIGNAL
#else /* ! MSG_NOSIGNAL */
-# define MAYBE_MSG_NOSIGNAL 0
+# define MSG_NOSIGNAL_OR_ZERO 0
#endif /* ! MSG_NOSIGNAL */
-#if !defined(SHUT_WR) && defined(SD_SEND)
+#if ! defined(SHUT_WR) && defined(SD_SEND)
# define SHUT_WR SD_SEND
#endif
-#if !defined(SHUT_RD) && defined(SD_RECEIVE)
+#if ! defined(SHUT_RD) && defined(SD_RECEIVE)
# define SHUT_RD SD_RECEIVE
#endif
-#if !defined(SHUT_RDWR) && defined(SD_BOTH)
+#if ! defined(SHUT_RDWR) && defined(SD_BOTH)
# define SHUT_RDWR SD_BOTH
#endif
-#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC))
+#if HAVE_ACCEPT4 + 0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || \
+ defined(SOCK_CLOEXEC) || defined(SOCK_NOSIGPIPE))
# define USE_ACCEPT4 1
#endif
@@ -194,29 +211,97 @@
#endif
+#if defined(TCP_CORK)
+/**
+ * Value of TCP_CORK or TCP_NOPUSH
+ */
+#define MHD_TCP_CORK_NOPUSH TCP_CORK
+#elif defined(TCP_NOPUSH)
+/**
+ * Value of TCP_CORK or TCP_NOPUSH
+ */
+#define MHD_TCP_CORK_NOPUSH TCP_NOPUSH
+#endif /* TCP_NOPUSH */
+
+
+#ifdef MHD_TCP_CORK_NOPUSH
+#ifdef __linux__
+/**
+ * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network
+ */
+#define _MHD_CORK_RESET_PUSH_DATA 1
+/**
+ * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network
+ * even if TCP_CORK/TCP_NOPUSH was in switched off state.
+ */
+#define _MHD_CORK_RESET_PUSH_DATA_ALWAYS 1
+#endif /* __linux__ */
+#if defined(__FreeBSD__) && \
+ ((__FreeBSD__ + 0) >= 5 || (__FreeBSD_version + 0) >= 450000)
+/* FreeBSD pushes data to the network with reset of TCP_NOPUSH
+ * starting from version 4.5. */
+/**
+ * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network
+ */
+#define _MHD_CORK_RESET_PUSH_DATA 1
+#endif /* __FreeBSD_version >= 450000 */
+#ifdef __OpenBSD__
+/* OpenBSD took implementation from FreeBSD */
+/**
+ * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network
+ */
+#define _MHD_CORK_RESET_PUSH_DATA 1
+#endif /* __OpenBSD__ */
+#endif /* MHD_TCP_CORK_NOPUSH */
+
+#ifdef __linux__
+/**
+ * Indicate that set of TCP_NODELAY push data to the network
+ */
+#define _MHD_NODELAY_SET_PUSH_DATA 1
+/**
+ * Indicate that set of TCP_NODELAY push data to the network even
+ * if TCP_DELAY was already set and regardless of TCP_CORK / TCP_NOPUSH state
+ */
+#define _MHD_NODELAY_SET_PUSH_DATA_ALWAYS 1
+#endif /* __linux__ */
+
+#ifdef MSG_MORE
+#ifdef __linux__
+/* MSG_MORE signal kernel to buffer outbond data and works like
+ * TCP_CORK per call without actually setting TCP_CORK value.
+ * It's known to work on Linux. Add more OSes if they are compatible. */
+/**
+ * Indicate MSG_MORE is usable for buffered send().
+ */
+#define MHD_USE_MSG_MORE 1
+#endif /* __linux__ */
+#endif /* MSG_MORE */
+
+
/**
* MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt()
*/
#ifdef MHD_POSIX_SOCKETS
- typedef int MHD_SCKT_OPT_BOOL_;
+typedef int MHD_SCKT_OPT_BOOL_;
#else /* MHD_WINSOCK_SOCKETS */
- typedef BOOL MHD_SCKT_OPT_BOOL_;
+typedef BOOL MHD_SCKT_OPT_BOOL_;
#endif /* MHD_WINSOCK_SOCKETS */
/**
* MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv
* functions
*/
-#if !defined(MHD_WINSOCK_SOCKETS)
- typedef size_t MHD_SCKT_SEND_SIZE_;
+#if ! defined(MHD_WINSOCK_SOCKETS)
+typedef size_t MHD_SCKT_SEND_SIZE_;
#else
- typedef int MHD_SCKT_SEND_SIZE_;
+typedef int MHD_SCKT_SEND_SIZE_;
#endif
/**
* MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value.
*/
-#if !defined(MHD_WINSOCK_SOCKETS)
+#if ! defined(MHD_WINSOCK_SOCKETS)
# define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX
#else
# define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX
@@ -232,10 +317,10 @@
* counted as success, only EBADF counts as an error!),
* boolean false otherwise.
*/
-#if !defined(MHD_WINSOCK_SOCKETS)
-# define MHD_socket_close_(fd) ((0 == close((fd))) || (EBADF != errno))
+#if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_socket_close_(fd) ((0 == close ((fd))) || (EBADF != errno))
#else
-# define MHD_socket_close_(fd) (0 == closesocket((fd)))
+# define MHD_socket_close_(fd) (0 == closesocket ((fd)))
#endif
/**
@@ -244,20 +329,32 @@
* @param fd socket to close
*/
#define MHD_socket_close_chk_(fd) do { \
- if (!MHD_socket_close_(fd)) \
- MHD_PANIC(_("Close socket failed.\n")); \
- } while(0)
+ if (! MHD_socket_close_ (fd)) \
+ MHD_PANIC (_ ("Close socket failed.\n")); \
+} while (0)
/**
- * MHD_send_ is wrapper for system's send()
+ * MHD_send4_ is a wrapper for system's send()
* @param s the socket to use
* @param b the buffer with data to send
* @param l the length of data in @a b
+ * @param f the additional flags
* @return ssize_t type value
*/
-#define MHD_send_(s,b,l) \
- ((ssize_t)send((s),(const void*)(b),((MHD_SCKT_SEND_SIZE_)l), MAYBE_MSG_NOSIGNAL))
+#define MHD_send4_(s,b,l,f) \
+ ((ssize_t) send ((s),(const void*) (b),(MHD_SCKT_SEND_SIZE_) (l), \
+ ((MSG_NOSIGNAL_OR_ZERO) | (f))))
+
+
+/**
+ * MHD_send_ is a simple wrapper for system's send()
+ * @param s the socket to use
+ * @param b the buffer with data to send
+ * @param l the length of data in @a b
+ * @return ssize_t type value
+ */
+#define MHD_send_(s,b,l) MHD_send4_((s),(b),(l), 0)
/**
@@ -268,7 +365,7 @@
* @return ssize_t type value
*/
#define MHD_recv_(s,b,l) \
- ((ssize_t)recv((s),(void*)(b),((MHD_SCKT_SEND_SIZE_)l), 0))
+ ((ssize_t) recv ((s),(void*) (b),(MHD_SCKT_SEND_SIZE_) (l), 0))
/**
@@ -281,11 +378,18 @@
* boolean false otherwise.
*/
#if defined(MHD_POSIX_SOCKETS)
-# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < ((MHD_socket)setsize))
+# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < \
+ ((MHD_socket) \
+ setsize))
#elif defined(MHD_WINSOCK_SOCKETS)
-# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*)(pset)==(void*)0) || \
- (((fd_set*)(pset))->fd_count < ((unsigned)setsize)) || \
- (FD_ISSET((fd),(pset))) )
+# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*) (pset)== \
+ (void*) 0) || \
+ (((fd_set*) (pset)) \
+ ->fd_count < \
+ ((unsigned) \
+ setsize)) || \
+ (FD_ISSET ((fd), \
+ (pset))) )
#endif
/**
@@ -296,7 +400,9 @@
* @return boolean true if FD can be added to fd_set,
* boolean false otherwise.
*/
-#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_((fd),(pset),FD_SETSIZE)
+#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_ ((fd), \
+ (pset), \
+ FD_SETSIZE)
/**
* Add FD to fd_set with specified FD_SETSIZE.
@@ -307,34 +413,35 @@
* system definition of FD_SET() is not used.
*/
#if defined(MHD_POSIX_SOCKETS)
-# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET((fd),(pset))
+# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET ((fd), \
+ (pset))
#elif defined(MHD_WINSOCK_SOCKETS)
# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \
- do { \
- u_int _i_ = 0; \
- fd_set* const _s_ = (fd_set*)(pset); \
- while((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array[_i_])) {++_i_;} \
- if ((_i_ == _s_->fd_count)) {_s_->fd_array[_s_->fd_count++] = (fd);} \
- } while(0)
+ do { \
+ u_int _i_ = 0; \
+ fd_set*const _s_ = (fd_set*) (pset); \
+ while ((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array [_i_])) {++_i_;} \
+ if ((_i_ == _s_->fd_count)) {_s_->fd_array [_s_->fd_count ++] = (fd);} \
+ } while (0)
#endif
- /* MHD_SYS_select_ is wrapper macro for system select() function */
-#if !defined(MHD_WINSOCK_SOCKETS)
-# define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
+/* MHD_SYS_select_ is wrapper macro for system select() function */
+#if ! defined(MHD_WINSOCK_SOCKETS)
+# define MHD_SYS_select_(n,r,w,e,t) select ((n),(r),(w),(e),(t))
#else
# define MHD_SYS_select_(n,r,w,e,t) \
-( ( (((void*)(r) == (void*)0) || ((fd_set*)(r))->fd_count == 0) && \
- (((void*)(w) == (void*)0) || ((fd_set*)(w))->fd_count == 0) && \
- (((void*)(e) == (void*)0) || ((fd_set*)(e))->fd_count == 0) ) ? \
- ( ((void*)(t) == (void*)0) ? 0 : \
- (Sleep(((struct timeval*)(t))->tv_sec * 1000 + \
- ((struct timeval*)(t))->tv_usec / 1000), 0) ) : \
- (select((int)0,(r),(w),(e),(t))) )
+ ( ( (((void*) (r) == (void*) 0) || ((fd_set*) (r))->fd_count == 0) && \
+ (((void*) (w) == (void*) 0) || ((fd_set*) (w))->fd_count == 0) && \
+ (((void*) (e) == (void*) 0) || ((fd_set*) (e))->fd_count == 0) ) ? \
+ ( ((void*) (t) == (void*) 0) ? 0 : \
+ (Sleep (((struct timeval*) (t))->tv_sec * 1000 \
+ + ((struct timeval*) (t))->tv_usec / 1000), 0) ) : \
+ (select ((int) 0,(r),(w),(e),(t))) )
#endif
#if defined(HAVE_POLL)
/* MHD_sys_poll_ is wrapper macro for system poll() function */
-# if !defined(MHD_WINSOCK_SOCKETS)
+# if ! defined(MHD_WINSOCK_SOCKETS)
# define MHD_sys_poll_ poll
# else /* MHD_WINSOCK_SOCKETS */
# define MHD_sys_poll_ WSAPoll
@@ -358,21 +465,24 @@
/* MHD_POLL_EVENTS_ERR_DISC is 'events' mask for errors and disconnect.
* Note: Out-of-band data is treated as error. */
-# if defined(_WIN32)
+# if defined(_WIN32) && ! defined(__CYGWIN__)
# define MHD_POLL_EVENTS_ERR_DISC POLLRDBAND
# elif defined(__linux__)
# define MHD_POLL_EVENTS_ERR_DISC POLLPRI
# else /* ! __linux__ */
-# define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO)
+# define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO \
+ | MHD_POLLRDBAND_OR_ZERO)
# endif /* ! __linux__ */
/* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect.
* Note: Out-of-band data is treated as error. */
# define MHD_POLL_REVENTS_ERR_DISC \
- (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR | POLLHUP)
+ (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
+ | POLLERR | POLLHUP)
/* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors.
* Note: Out-of-band data is treated as error. */
# define MHD_POLL_REVENTS_ERRROR \
- (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR)
+ (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
+ | POLLERR)
#endif /* HAVE_POLL */
#define MHD_SCKT_MISSING_ERR_CODE_ 31450
@@ -447,6 +557,11 @@
# else /* ! EINVAL */
# define MHD_SCKT_EINVAL_ MHD_SCKT_MISSING_ERR_CODE_
# endif /* ! EINVAL */
+# ifdef EPIPE
+# define MHD_SCKT_EPIPE_ EPIPE
+# else /* ! EPIPE */
+# define MHD_SCKT_EPIPE_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! EPIPE */
# ifdef EFAULT
# define MHD_SCKT_EFAUL_ EFAULT
# else /* ! EFAULT */
@@ -457,6 +572,11 @@
# else /* ! ENOSYS */
# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
# endif /* ! ENOSYS */
+# ifdef ENOPROTOOPT
+# define MHD_SCKT_ENOPROTOOPT_ ENOPROTOOPT
+# else /* ! ENOPROTOOPT */
+# define MHD_SCKT_ENOPROTOOPT_ MHD_SCKT_MISSING_ERR_CODE_
+# endif /* ! ENOPROTOOPT */
# ifdef ENOTSUP
# define MHD_SCKT_ENOTSUP_ ENOTSUP
# else /* ! ENOTSUP */
@@ -491,8 +611,10 @@
# define MHD_SCKT_EBADF_ WSAEBADF
# define MHD_SCKT_ENOTSOCK_ WSAENOTSOCK
# define MHD_SCKT_EINVAL_ WSAEINVAL
+# define MHD_SCKT_EPIPE_ WSAESHUTDOWN
# define MHD_SCKT_EFAUL_ WSAEFAULT
# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
+# define MHD_SCKT_ENOPROTOOPT_ WSAENOPROTOOPT
# define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_
# define MHD_SCKT_EOPNOTSUPP_ WSAEOPNOTSUPP
# define MHD_SCKT_EACCESS_ WSAEACCES
@@ -506,30 +628,31 @@
#if defined(MHD_POSIX_SOCKETS)
# define MHD_socket_get_error_() (errno)
#elif defined(MHD_WINSOCK_SOCKETS)
-# define MHD_socket_get_error_() WSAGetLastError()
+# define MHD_socket_get_error_() WSAGetLastError ()
#endif
#ifdef MHD_WINSOCK_SOCKETS
- /* POSIX-W32 sockets compatibility functions */
+/* POSIX-W32 sockets compatibility functions */
/**
* Return pointer to string description of specified WinSock error
* @param err the WinSock error code.
* @return pointer to string description of specified WinSock error.
*/
- const char* MHD_W32_strerror_winsock_(int err);
+const char*MHD_W32_strerror_winsock_ (int err);
+
#endif /* MHD_WINSOCK_SOCKETS */
/* MHD_socket_last_strerr_ is description string of specified socket error code */
#if defined(MHD_POSIX_SOCKETS)
-# define MHD_socket_strerr_(err) strerror((err))
+# define MHD_socket_strerr_(err) strerror ((err))
#elif defined(MHD_WINSOCK_SOCKETS)
-# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err))
+# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_ ((err))
#endif
/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
* description string of last socket error (W32) */
-#define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_())
+#define MHD_socket_last_strerr_() MHD_socket_strerr_ (MHD_socket_get_error_ ())
/**
* MHD_socket_fset_error_() set socket system native error code.
@@ -537,7 +660,7 @@
#if defined(MHD_POSIX_SOCKETS)
# define MHD_socket_fset_error_(err) (errno = (err))
#elif defined(MHD_WINSOCK_SOCKETS)
-# define MHD_socket_fset_error_(err) (WSASetLastError((err)))
+# define MHD_socket_fset_error_(err) (WSASetLastError ((err)))
#endif
/**
@@ -549,7 +672,8 @@
* and error was not set.
*/
#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \
- (MHD_socket_fset_error_((err)), !0) : 0 )
+ (MHD_socket_fset_error_ ((err)), ! 0) : \
+ 0)
/**
* MHD_socket_set_error_() set socket system native error code to
@@ -562,7 +686,8 @@
(errno = ENOSYS) : (errno = (err)) )
# elif defined(EOPNOTSUPP)
# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
- (errno = EOPNOTSUPP) : (errno = (err)) )
+ (errno = EOPNOTSUPP) : (errno = \
+ (err)) )
# elif defined (EFAULT)
# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
(errno = EFAULT) : (errno = (err)) )
@@ -570,13 +695,14 @@
# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
(errno = EINVAL) : (errno = (err)) )
# else /* !EOPNOTSUPP && !EFAULT && !EINVAL */
-# warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
+# warning \
+ No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
# define MHD_socket_set_error_(err) (errno = (err))
# endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/
#elif defined(MHD_WINSOCK_SOCKETS)
# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
- (WSASetLastError((WSAEOPNOTSUPP))) : \
- (WSASetLastError((err))) )
+ (WSASetLastError ((WSAEOPNOTSUPP))) : \
+ (WSASetLastError ((err))) )
#endif
/**
@@ -600,7 +726,8 @@
* last socket error equals to MHD_SCKT_E*_ @a code;
* boolean false otherwise
*/
-#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code))
+#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_ (MHD_socket_get_error_ (), \
+ (code))
/* Specific error code checks */
@@ -610,7 +737,7 @@
* @return boolean true if @a err is equal to sockets' EINTR code;
* boolean false otherwise.
*/
-#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_)
+#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EINTR_)
/**
* Check whether given socket error is equal to system's
@@ -619,10 +746,12 @@
* boolean false otherwise.
*/
#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_
-# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_)
+# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EAGAIN_)
#else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
-# define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \
- MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) )
+# define MHD_SCKT_ERR_IS_EAGAIN_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EAGAIN_) || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EWOULDBLOCK_) )
#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
/**
@@ -630,10 +759,17 @@
* @return boolean true if @a err is any kind of "low resource" error,
* boolean false otherwise.
*/
-#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \
- MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \
- MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \
- MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) )
+#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_EMFILE_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENFILE_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENOMEM_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ENOBUFS_) )
/**
* Check whether is given socket error is type of "incoming connection
@@ -642,9 +778,11 @@
* boolean false otherwise.
*/
#if defined(MHD_POSIX_SOCKETS)
-# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)
+# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNABORTED_)
#elif defined(MHD_WINSOCK_SOCKETS)
-# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_)
+# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNRESET_)
#endif
/**
@@ -653,8 +791,11 @@
* @return boolean true is @a err match described socket error code,
* boolean false otherwise.
*/
-#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \
- MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_))
+#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) (MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNRESET_) \
+ || \
+ MHD_SCKT_ERR_IS_ ((err), \
+ MHD_SCKT_ECONNABORTED_))
/* Specific error code set */
@@ -663,12 +804,16 @@
* available on platform.
*/
#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_
-# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOMEM_)
#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_
-# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_)
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOBUFS_)
#else
-# warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
-# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
+# warning \
+ No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
+# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
+ MHD_SCKT_ENOMEM_)
#endif
/* Socket functions */
@@ -680,22 +825,26 @@
#endif /* AF_UNIX */
#if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL)
-# define MHD_socket_pair_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr)))
+# define MHD_socket_pair_(fdarr) (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM, 0, \
+ (fdarr)))
# if defined(HAVE_SOCK_NONBLOCK)
-# define MHD_socket_pair_nblk_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr)))
+# define MHD_socket_pair_nblk_(fdarr) (! socketpair (MHD_SCKT_LOCAL, \
+ SOCK_STREAM \
+ | SOCK_NONBLOCK, 0, \
+ (fdarr)))
# endif /* HAVE_SOCK_NONBLOCK*/
#elif defined(MHD_WINSOCK_SOCKETS)
- /**
- * Create pair of mutually connected TCP/IP sockets on loopback address
- * @param sockets_pair array to receive resulted sockets
- * @param non_blk if set to non-zero value, sockets created in non-blocking mode
- * otherwise sockets will be in blocking mode
- * @return non-zero if succeeded, zero otherwise
- */
- int MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk);
+/**
+ * Create pair of mutually connected TCP/IP sockets on loopback address
+ * @param sockets_pair array to receive resulted sockets
+ * @param non_blk if set to non-zero value, sockets created in non-blocking mode
+ * otherwise sockets will be in blocking mode
+ * @return non-zero if succeeded, zero otherwise
+ */
+int MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk);
-# define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_((fdarr), 0)
-# define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_((fdarr), 1)
+# define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_ ((fdarr), 0)
+# define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_ ((fdarr), 1)
#endif
/**
@@ -726,6 +875,19 @@
/**
+ * Disable Nagle's algorithm on @a sock. This is what we do by default for
+ * all TCP sockets in MHD, unless the platform does not support the MSG_MORE
+ * or MSG_CORK or MSG_NOPUSH options.
+ *
+ * @param sock socket to manipulate
+ * @param on value to use
+ * @return 0 on success
+ */
+int
+MHD_socket_set_nodelay_ (MHD_socket sock,
+ bool on);
+
+/**
* Change socket options to be non-inheritable.
*
* @param sock socket to manipulate
@@ -737,24 +899,44 @@
#if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE)
- static const int _MHD_socket_int_one = 1;
+static const int _MHD_socket_int_one = 1;
/**
* Change socket options to no signal on remote disconnect.
*
* @param sock socket to manipulate
* @return non-zero if succeeded, zero otherwise
*/
-# define MHD_socket_nosignal_(sock) \
- (!setsockopt((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one,sizeof(_MHD_socket_int_one)))
+#define MHD_socket_nosignal_(sock) \
+ (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \
+ sizeof(_MHD_socket_int_one)))
#endif /* SOL_SOCKET && SO_NOSIGPIPE */
+
+#if defined(MHD_socket_nosignal_) || defined(MSG_NOSIGNAL)
+/**
+ * Indicate that SIGPIPE can be suppressed by MHD for normal send() by flags
+ * or socket options.
+ * If this macro is undefined, MHD cannot suppress SIGPIPE for normal
+ * processing so sendfile() or writev() calls is not avoided.
+ */
+#define MHD_SEND_SPIPE_SUPPRESS_POSSIBLE 1
+#endif /* MHD_WINSOCK_SOCKETS || MHD_socket_nosignal_ || MSG_NOSIGNAL */
+
+#if ! defined(MHD_WINSOCK_SOCKETS)
+/**
+ * Indicate that suppression of SIGPIPE is required.
+ */
+#define MHD_SEND_SPIPE_SUPPRESS_NEEDED 1
+#endif
+
/**
* Create a listen socket, with noninheritable flag if possible.
*
- * @param use_ipv6 if set to non-zero IPv6 is used
+ * @param pf protocol family to use
* @return created socket or MHD_INVALID_SOCKET in case of errors
*/
MHD_socket
-MHD_socket_create_listen_ (int use_ipv6);
+MHD_socket_create_listen_ (int pf);
+
#endif /* ! MHD_SOCKETS_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_str.c
^
|
@@ -32,13 +32,13 @@
#include "mhd_limits.h"
#ifdef MHD_FAVOR_SMALL_CODE
-#ifdef _MHD_inline
-#undef _MHD_inline
-#endif /* _MHD_inline */
+#ifdef _MHD_static_inline
+#undef _MHD_static_inline
+#endif /* _MHD_static_inline */
/* Do not force inlining and do not use macro functions, use normal static
functions instead.
This may give more flexibility for size optimizations. */
-#define _MHD_inline static
+#define _MHD_static_inline static
#ifndef INLINE_FUNC
#define INLINE_FUNC 1
#endif /* !INLINE_FUNC */
@@ -50,70 +50,80 @@
*/
#ifdef INLINE_FUNC
+
+#if 0 /* Disable unused functions. */
/**
* Check whether character is lower case letter in US-ASCII
*
* @param c character to check
* @return non-zero if character is lower case letter, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciilower (char c)
{
return (c >= 'a') && (c <= 'z');
}
+#endif /* Disable unused functions. */
+
+
/**
* Check whether character is upper case letter in US-ASCII
*
* @param c character to check
* @return non-zero if character is upper case letter, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciiupper (char c)
{
return (c >= 'A') && (c <= 'Z');
}
+#if 0 /* Disable unused functions. */
/**
* Check whether character is letter in US-ASCII
*
* @param c character to check
* @return non-zero if character is letter in US-ASCII, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciialpha (char c)
{
return isasciilower (c) || isasciiupper (c);
}
+#endif /* Disable unused functions. */
+
+
/**
* Check whether character is decimal digit in US-ASCII
*
* @param c character to check
* @return non-zero if character is decimal digit, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciidigit (char c)
{
return (c >= '0') && (c <= '9');
}
+#if 0 /* Disable unused functions. */
/**
* Check whether character is hexadecimal digit in US-ASCII
*
* @param c character to check
* @return non-zero if character is decimal digit, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciixdigit (char c)
{
return isasciidigit (c) ||
- ( (c >= 'A') && (c <= 'F') ) ||
- ( (c >= 'a') && (c <= 'f') );
+ ( (c >= 'A') && (c <= 'F') ) ||
+ ( (c >= 'a') && (c <= 'f') );
}
@@ -123,13 +133,16 @@
* @param c character to check
* @return non-zero if character is decimal digit or letter, zero otherwise
*/
-_MHD_inline bool
+_MHD_static_inline bool
isasciialnum (char c)
{
return isasciialpha (c) || isasciidigit (c);
}
+#endif /* Disable unused functions. */
+
+
/**
* Convert US-ASCII character to lower case.
* If character is upper case letter in US-ASCII than it's converted to lower
@@ -139,13 +152,14 @@
* @param c character to convert
* @return converted to lower case character
*/
-_MHD_inline char
+_MHD_static_inline char
toasciilower (char c)
{
return isasciiupper (c) ? (c - 'A' + 'a') : c;
}
+#if 0 /* Disable unused functions. */
/**
* Convert US-ASCII character to upper case.
* If character is lower case letter in US-ASCII than it's converted to upper
@@ -155,47 +169,56 @@
* @param c character to convert
* @return converted to upper case character
*/
-_MHD_inline char
+_MHD_static_inline char
toasciiupper (char c)
{
return isasciilower (c) ? (c - 'a' + 'A') : c;
}
+#endif /* Disable unused functions. */
+
+
+#if defined(MHD_FAVOR_SMALL_CODE) /* Used only in MHD_str_to_uvalue_n_() */
/**
* Convert US-ASCII decimal digit to its value.
*
* @param c character to convert
* @return value of decimal digit or -1 if @ c is not decimal digit
*/
-_MHD_inline int
+_MHD_static_inline int
todigitvalue (char c)
{
if (isasciidigit (c))
- return (unsigned char)(c - '0');
+ return (unsigned char) (c - '0');
return -1;
}
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+
/**
* Convert US-ASCII hexadecimal digit to its value.
*
* @param c character to convert
* @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
*/
-_MHD_inline int
+_MHD_static_inline int
toxdigitvalue (char c)
{
if (isasciidigit (c))
- return (unsigned char)(c - '0');
+ return (unsigned char) (c - '0');
if ( (c >= 'A') && (c <= 'F') )
- return (unsigned char)(c - 'A' + 10);
+ return (unsigned char) (c - 'A' + 10);
if ( (c >= 'a') && (c <= 'f') )
- return (unsigned char)(c - 'a' + 10);
+ return (unsigned char) (c - 'a' + 10);
return -1;
}
+
+
#else /* !INLINE_FUNC */
@@ -206,7 +229,7 @@
* @return boolean true if character is lower case letter,
* boolean false otherwise
*/
-#define isasciilower(c) (((char)(c)) >= 'a' && ((char)(c)) <= 'z')
+#define isasciilower(c) (((char) (c)) >= 'a' && ((char) (c)) <= 'z')
/**
@@ -216,7 +239,7 @@
* @return boolean true if character is upper case letter,
* boolean false otherwise
*/
-#define isasciiupper(c) (((char)(c)) >= 'A' && ((char)(c)) <= 'Z')
+#define isasciiupper(c) (((char) (c)) >= 'A' && ((char) (c)) <= 'Z')
/**
@@ -226,7 +249,7 @@
* @return boolean true if character is letter, boolean false
* otherwise
*/
-#define isasciialpha(c) (isasciilower(c) || isasciiupper(c))
+#define isasciialpha(c) (isasciilower (c) || isasciiupper (c))
/**
@@ -236,7 +259,7 @@
* @return boolean true if character is decimal digit, boolean false
* otherwise
*/
-#define isasciidigit(c) (((char)(c)) >= '0' && ((char)(c)) <= '9')
+#define isasciidigit(c) (((char) (c)) >= '0' && ((char) (c)) <= '9')
/**
@@ -246,9 +269,9 @@
* @return boolean true if character is hexadecimal digit,
* boolean false otherwise
*/
-#define isasciixdigit(c) (isasciidigit((c)) || \
- (((char)(c)) >= 'A' && ((char)(c)) <= 'F') || \
- (((char)(c)) >= 'a' && ((char)(c)) <= 'f') )
+#define isasciixdigit(c) (isasciidigit ((c)) || \
+ (((char) (c)) >= 'A' && ((char) (c)) <= 'F') || \
+ (((char) (c)) >= 'a' && ((char) (c)) <= 'f') )
/**
@@ -258,7 +281,7 @@
* @return boolean true if character is decimal digit or letter,
* boolean false otherwise
*/
-#define isasciialnum(c) (isasciialpha(c) || isasciidigit(c))
+#define isasciialnum(c) (isasciialpha (c) || isasciidigit (c))
/**
@@ -270,7 +293,8 @@
* @param c character to convert
* @return converted to lower case character
*/
-#define toasciilower(c) ((isasciiupper(c)) ? (((char)(c)) - 'A' + 'a') : ((char)(c)))
+#define toasciilower(c) ((isasciiupper (c)) ? (((char) (c)) - 'A' + 'a') : \
+ ((char) (c)))
/**
@@ -282,7 +306,8 @@
* @param c character to convert
* @return converted to upper case character
*/
-#define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c)))
+#define toasciiupper(c) ((isasciilower (c)) ? (((char) (c)) - 'a' + 'A') : \
+ ((char) (c)))
/**
@@ -291,7 +316,8 @@
* @param c character to convert
* @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
*/
-#define todigitvalue(c) (isasciidigit(c) ? (int)(((char)(c)) - '0') : (int)(-1))
+#define todigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
+ (int) (-1))
/**
@@ -299,11 +325,12 @@
* @param c character to convert
* @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
*/
-#define toxdigitvalue(c) ( isasciidigit(c) ? (int)(((char)(c)) - '0') : \
- ( (((char)(c)) >= 'A' && ((char)(c)) <= 'F') ? \
- (int)(((unsigned char)(c)) - 'A' + 10) : \
- ( (((char)(c)) >= 'a' && ((char)(c)) <= 'f') ? \
- (int)(((unsigned char)(c)) - 'a' + 10) : (int)(-1) )))
+#define toxdigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
+ ( (((char) (c)) >= 'A' && ((char) (c)) <= 'F') ? \
+ (int) (((unsigned char) (c)) - 'A' + 10) : \
+ ( (((char) (c)) >= 'a' && ((char) (c)) <= 'f') ? \
+ (int) (((unsigned char) (c)) - 'a' + 10) : \
+ (int) (-1) )))
#endif /* !INLINE_FUNC */
@@ -316,21 +343,23 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
int
-MHD_str_equal_caseless_ (const char * str1,
- const char * str2)
+MHD_str_equal_caseless_ (const char *str1,
+ const char *str2)
{
while (0 != (*str1))
- {
- const char c1 = *str1;
- const char c2 = *str2;
- if ( (c1 != c2) &&
- (toasciilower (c1) != toasciilower (c2)) )
- return 0;
- str1++;
- str2++;
- }
+ {
+ const char c1 = *str1;
+ const char c2 = *str2;
+ if ( (c1 != c2) &&
+ (toasciilower (c1) != toasciilower (c2)) )
+ return 0;
+ str1++;
+ str2++;
+ }
return 0 == (*str2);
}
+
+
#endif /* ! MHD_FAVOR_SMALL_CODE */
@@ -346,23 +375,51 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
int
-MHD_str_equal_caseless_n_ (const char * const str1,
- const char * const str2,
+MHD_str_equal_caseless_n_ (const char *const str1,
+ const char *const str2,
size_t maxlen)
{
size_t i;
for (i = 0; i < maxlen; ++i)
- {
- const char c1 = str1[i];
- const char c2 = str2[i];
- if (0 == c2)
- return 0 == c1;
- if ( (c1 != c2) &&
- (toasciilower (c1) != toasciilower (c2)) )
- return 0;
- }
- return !0;
+ {
+ const char c1 = str1[i];
+ const char c2 = str2[i];
+ if (0 == c2)
+ return 0 == c1;
+ if ( (c1 != c2) &&
+ (toasciilower (c1) != toasciilower (c2)) )
+ return 0;
+ }
+ return ! 0;
+}
+
+
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters and
+ * checking exactly @a len characters.
+ * Compares exactly @a len characters, including binary zero characters.
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @param len number of characters to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+bool
+MHD_str_equal_caseless_bin_n_ (const char *const str1,
+ const char *const str2,
+ size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ {
+ const char c1 = str1[i];
+ const char c2 = str2[i];
+ if ( (c1 != c2) &&
+ (toasciilower (c1) != toasciilower (c2)) )
+ return 0;
+ }
+ return ! 0;
}
@@ -380,49 +437,53 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
bool
-MHD_str_has_token_caseless_ (const char * str,
- const char * const token,
+MHD_str_has_token_caseless_ (const char *str,
+ const char *const token,
size_t token_len)
{
if (0 == token_len)
return false;
while (0 != *str)
- {
- size_t i;
- /* Skip all whitespaces and empty tokens. */
- while (' ' == *str || '\t' == *str || ',' == *str) str++;
-
- /* Check for token match. */
- i = 0;
- while (1)
- {
- const char sc = *(str++);
- const char tc = token[i++];
-
- if (0 == sc)
- return false;
- if ( (sc != tc) &&
- (toasciilower (sc) != toasciilower (tc)) )
- break;
- if (i >= token_len)
- {
- /* Check whether substring match token fully or
- * has additional unmatched chars at tail. */
- while (' ' == *str || '\t' == *str) str++;
- /* End of (sub)string? */
- if (0 == *str || ',' == *str)
- return true;
- /* Unmatched chars at end of substring. */
- break;
- }
- }
- /* Find next substring. */
- while (0 != *str && ',' != *str) str++;
+ {
+ size_t i;
+ /* Skip all whitespaces and empty tokens. */
+ while (' ' == *str || '\t' == *str || ',' == *str)
+ str++;
+
+ /* Check for token match. */
+ i = 0;
+ while (1)
+ {
+ const char sc = *(str++);
+ const char tc = token[i++];
+
+ if (0 == sc)
+ return false;
+ if ( (sc != tc) &&
+ (toasciilower (sc) != toasciilower (tc)) )
+ break;
+ if (i >= token_len)
+ {
+ /* Check whether substring match token fully or
+ * has additional unmatched chars at tail. */
+ while (' ' == *str || '\t' == *str)
+ str++;
+ /* End of (sub)string? */
+ if ((0 == *str) || (',' == *str) )
+ return true;
+ /* Unmatched chars at end of substring. */
+ break;
+ }
}
+ /* Find next substring. */
+ while (0 != *str && ',' != *str)
+ str++;
+ }
return false;
}
+
#ifndef MHD_FAVOR_SMALL_CODE
/* Use individual function for each case */
@@ -440,25 +501,25 @@
MHD_str_to_uint64_ (const char *str,
uint64_t *out_val)
{
- const char * const start = str;
+ const char *const start = str;
uint64_t res;
- if (!str || !out_val || !isasciidigit(str[0]))
+ if (! str || ! out_val || ! isasciidigit (str[0]))
return 0;
res = 0;
do
- {
- const int digit = (unsigned char)(*str) - '0';
- if ( (res > (UINT64_MAX / 10)) ||
- ( (res == (UINT64_MAX / 10)) &&
- ((uint64_t)digit > (UINT64_MAX % 10)) ) )
- return 0;
-
- res *= 10;
- res += digit;
- str++;
- } while (isasciidigit (*str));
+ {
+ const int digit = (unsigned char) (*str) - '0';
+ if ( (res > (UINT64_MAX / 10)) ||
+ ( (res == (UINT64_MAX / 10)) &&
+ ((uint64_t) digit > (UINT64_MAX % 10)) ) )
+ return 0;
+
+ res *= 10;
+ res += digit;
+ str++;
+ } while (isasciidigit (*str));
*out_val = res;
return str - start;
@@ -479,34 +540,34 @@
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_str_to_uint64_n_ (const char * str,
+MHD_str_to_uint64_n_ (const char *str,
size_t maxlen,
uint64_t *out_val)
{
uint64_t res;
size_t i;
- if (!str || !maxlen || !out_val || !isasciidigit (str[0]))
+ if (! str || ! maxlen || ! out_val || ! isasciidigit (str[0]))
return 0;
res = 0;
i = 0;
do
- {
- const int digit = (unsigned char)str[i] - '0';
+ {
+ const int digit = (unsigned char) str[i] - '0';
- if ( (res > (UINT64_MAX / 10)) ||
- ( (res == (UINT64_MAX / 10)) &&
- ((uint64_t)digit > (UINT64_MAX % 10)) ) )
- return 0;
-
- res *= 10;
- res += digit;
- i++;
- } while ( (i < maxlen) &&
- isasciidigit (str[i]) );
+ if ( (res > (UINT64_MAX / 10)) ||
+ ( (res == (UINT64_MAX / 10)) &&
+ ((uint64_t) digit > (UINT64_MAX % 10)) ) )
+ return 0;
+
+ res *= 10;
+ res += digit;
+ i++;
+ } while ( (i < maxlen) &&
+ isasciidigit (str[i]) );
- *out_val= res;
+ *out_val = res;
return i;
}
@@ -522,31 +583,32 @@
* then possible to store in uint32_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint32_ (const char * str,
+MHD_strx_to_uint32_ (const char *str,
uint32_t *out_val)
{
- const char * const start = str;
+ const char *const start = str;
uint32_t res;
int digit;
- if (!str || !out_val)
+ if (! str || ! out_val)
return 0;
res = 0;
digit = toxdigitvalue (*str);
while (digit >= 0)
+ {
+ if ( (res < (UINT32_MAX / 16)) ||
+ ((res == (UINT32_MAX / 16)) && ( (uint32_t) digit <= (UINT32_MAX
+ % 16)) ) )
{
- if ( (res < (UINT32_MAX / 16)) ||
- (res == (UINT32_MAX / 16) && (uint32_t)digit <= (UINT32_MAX % 16)) )
- {
- res *= 16;
- res += digit;
- }
- else
- return 0;
- str++;
- digit = toxdigitvalue (*str);
+ res *= 16;
+ res += digit;
}
+ else
+ return 0;
+ str++;
+ digit = toxdigitvalue (*str);
+ }
if (str - start > 0)
*out_val = res;
@@ -575,21 +637,22 @@
size_t i;
uint32_t res;
int digit;
- if (!str || !out_val)
+ if (! str || ! out_val)
return 0;
res = 0;
i = 0;
while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
- {
- if ( (res > (UINT32_MAX / 16)) ||
- (res == (UINT32_MAX / 16) && (uint32_t)digit > (UINT32_MAX % 16)) )
- return 0;
-
- res *= 16;
- res += digit;
- i++;
- }
+ {
+ if ( (res > (UINT32_MAX / 16)) ||
+ ((res == (UINT32_MAX / 16)) && ( (uint32_t) digit > (UINT32_MAX
+ % 16)) ) )
+ return 0;
+
+ res *= 16;
+ res += digit;
+ i++;
+ }
if (i)
*out_val = res;
@@ -611,27 +674,28 @@
MHD_strx_to_uint64_ (const char *str,
uint64_t *out_val)
{
- const char * const start = str;
+ const char *const start = str;
uint64_t res;
int digit;
- if (!str || !out_val)
+ if (! str || ! out_val)
return 0;
res = 0;
digit = toxdigitvalue (*str);
while (digit >= 0)
+ {
+ if ( (res < (UINT64_MAX / 16)) ||
+ ((res == (UINT64_MAX / 16)) && ( (uint64_t) digit <= (UINT64_MAX
+ % 16)) ) )
{
- if ( (res < (UINT64_MAX / 16)) ||
- (res == (UINT64_MAX / 16) && (uint64_t)digit <= (UINT64_MAX % 16)) )
- {
- res *= 16;
- res += digit;
- }
- else
- return 0;
- str++;
- digit = toxdigitvalue (*str);
+ res *= 16;
+ res += digit;
}
+ else
+ return 0;
+ str++;
+ digit = toxdigitvalue (*str);
+ }
if (str - start > 0)
*out_val = res;
@@ -653,34 +717,36 @@
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint64_n_ (const char * str,
+MHD_strx_to_uint64_n_ (const char *str,
size_t maxlen,
uint64_t *out_val)
{
size_t i;
uint64_t res;
int digit;
- if (!str || !out_val)
+ if (! str || ! out_val)
return 0;
res = 0;
i = 0;
while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
- {
- if ( (res > (UINT64_MAX / 16)) ||
- (res == (UINT64_MAX / 16) && (uint64_t)digit > (UINT64_MAX % 16)) )
- return 0;
-
- res *= 16;
- res += digit;
- i++;
- }
+ {
+ if ( (res > (UINT64_MAX / 16)) ||
+ ((res == (UINT64_MAX / 16)) && ( (uint64_t) digit > (UINT64_MAX
+ % 16)) ) )
+ return 0;
+
+ res *= 16;
+ res += digit;
+ i++;
+ }
if (i)
*out_val = res;
return i;
}
+
#else /* MHD_FAVOR_SMALL_CODE */
/**
@@ -703,7 +769,7 @@
size_t
MHD_str_to_uvalue_n_ (const char *str,
size_t maxlen,
- void * out_val,
+ void *out_val,
size_t val_size,
uint64_t max_val,
int base)
@@ -715,34 +781,36 @@
const uint64_t max_v_mod_b = max_val % base;
/* 'digit->value' must be function, not macro */
int (*const dfunc)(char) = (base == 16) ?
- toxdigitvalue : todigitvalue;
+ toxdigitvalue : todigitvalue;
- if ( !str || !out_val ||
- (base != 16 && base != 10) )
+ if (! str || ! out_val ||
+ ((base != 16) && (base != 10)) )
return 0;
res = 0;
i = 0;
while (maxlen > i && 0 <= (digit = dfunc (str[i])))
- {
- if ( ((max_v_div_b) < res) ||
- ((max_v_div_b) == res && (max_v_mod_b) < (uint64_t)digit) )
- return 0;
-
- res *= base;
- res += digit;
- i++;
- }
+ {
+ if ( ((max_v_div_b) < res) ||
+ (( (max_v_div_b) == res) && ( (max_v_mod_b) < (uint64_t) digit) ) )
+ return 0;
+
+ res *= base;
+ res += digit;
+ i++;
+ }
if (i)
- {
- if (8 == val_size)
- *(uint64_t*)out_val = res;
- else if (4 == val_size)
- *(uint32_t*)out_val = (uint32_t)res;
- else
- return 0;
- }
+ {
+ if (8 == val_size)
+ *(uint64_t*) out_val = res;
+ else if (4 == val_size)
+ *(uint32_t*) out_val = (uint32_t) res;
+ else
+ return 0;
+ }
return i;
}
+
+
#endif /* MHD_FAVOR_SMALL_CODE */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_str.h
^
|
@@ -29,7 +29,7 @@
#include "mhd_options.h"
#include <stdint.h>
-#include <stdlib.h>
+#include <stddef.h>
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#endif /* HAVE_STDBOOL_H */
@@ -42,7 +42,7 @@
/**
* Determine length of static string / macro strings at compile time.
*/
-#define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1)
+#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
#endif /* ! MHD_STATICSTR_LEN_ */
/*
@@ -58,11 +58,13 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
int
-MHD_str_equal_caseless_ (const char * str1,
- const char * str2);
+MHD_str_equal_caseless_ (const char *str1,
+ const char *str2);
+
#else /* MHD_FAVOR_SMALL_CODE */
/* Reuse MHD_str_equal_caseless_n_() to reduce size */
-#define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_((s1),(s2), SIZE_MAX)
+#define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_ ((s1),(s2), \
+ SIZE_MAX)
#endif /* MHD_FAVOR_SMALL_CODE */
@@ -77,9 +79,24 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
int
-MHD_str_equal_caseless_n_ (const char * const str1,
- const char * const str2,
- size_t maxlen);
+MHD_str_equal_caseless_n_ (const char *const str1,
+ const char *const str2,
+ size_t maxlen);
+
+
+/**
+ * Check two string for equality, ignoring case of US-ASCII letters and
+ * checking exactly @a len characters.
+ * Compares exactly @a len characters, including binary zero characters.
+ * @param str1 first string to compare
+ * @param str2 second string to compare
+ * @param len number of characters to compare
+ * @return non-zero if two strings are equal, zero otherwise.
+ */
+bool
+MHD_str_equal_caseless_bin_n_ (const char *const str1,
+ const char *const str2,
+ size_t len);
/**
@@ -96,8 +113,8 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
bool
-MHD_str_has_token_caseless_ (const char * str,
- const char * const token,
+MHD_str_has_token_caseless_ (const char *str,
+ const char *const token,
size_t token_len);
/**
@@ -111,7 +128,7 @@
* @return non-zero if two strings are equal, zero otherwise.
*/
#define MHD_str_has_s_token_caseless_(str,tkn) \
- MHD_str_has_token_caseless_((str),(tkn),MHD_STATICSTR_LEN_(tkn))
+ MHD_str_has_token_caseless_ ((str),(tkn),MHD_STATICSTR_LEN_ (tkn))
#ifndef MHD_FAVOR_SMALL_CODE
/* Use individual function for each case to improve speed */
@@ -126,13 +143,13 @@
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_str_to_uint64_ (const char * str,
- uint64_t * out_val);
+MHD_str_to_uint64_ (const char *str,
+ uint64_t *out_val);
/**
* Convert not more then @a maxlen decimal US-ASCII digits in string to
* number in uint64_t.
- * Conversion stopped at first non-digit character or after @a maxlen
+ * Conversion stopped at first non-digit character or after @a maxlen
* digits.
* @param str string to convert
* @param maxlen maximum number of characters to process
@@ -142,9 +159,9 @@
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_str_to_uint64_n_ (const char * str,
+MHD_str_to_uint64_n_ (const char *str,
size_t maxlen,
- uint64_t * out_val);
+ uint64_t *out_val);
/**
@@ -152,19 +169,19 @@
* Conversion stopped at first non-digit character.
* @param str string to convert
* @param out_val pointer to uint32_t to store result of conversion
- * @return non-zero number of characters processed on succeed,
+ * @return non-zero number of characters processed on succeed,
* zero if no digit is found, resulting value is larger
* then possible to store in uint32_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint32_ (const char * str,
- uint32_t * out_val);
+MHD_strx_to_uint32_ (const char *str,
+ uint32_t *out_val);
/**
* Convert not more then @a maxlen hexadecimal US-ASCII digits in string
* to number in uint32_t.
- * Conversion stopped at first non-digit character or after @a maxlen
+ * Conversion stopped at first non-digit character or after @a maxlen
* digits.
* @param str string to convert
* @param maxlen maximum number of characters to process
@@ -174,9 +191,9 @@
* then possible to store in uint32_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint32_n_ (const char * str,
- size_t maxlen,
- uint32_t * out_val);
+MHD_strx_to_uint32_n_ (const char *str,
+ size_t maxlen,
+ uint32_t *out_val);
/**
@@ -184,19 +201,19 @@
* Conversion stopped at first non-digit character.
* @param str string to convert
* @param out_val pointer to uint64_t to store result of conversion
- * @return non-zero number of characters processed on succeed,
+ * @return non-zero number of characters processed on succeed,
* zero if no digit is found, resulting value is larger
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint64_ (const char * str,
- uint64_t * out_val);
+MHD_strx_to_uint64_ (const char *str,
+ uint64_t *out_val);
/**
* Convert not more then @a maxlen hexadecimal US-ASCII digits in string
* to number in uint64_t.
- * Conversion stopped at first non-digit character or after @a maxlen
+ * Conversion stopped at first non-digit character or after @a maxlen
* digits.
* @param str string to convert
* @param maxlen maximum number of characters to process
@@ -206,9 +223,9 @@
* then possible to store in uint64_t or @a out_val is NULL
*/
size_t
-MHD_strx_to_uint64_n_ (const char * str,
+MHD_strx_to_uint64_n_ (const char *str,
size_t maxlen,
- uint64_t * out_val);
+ uint64_t *out_val);
#else /* MHD_FAVOR_SMALL_CODE */
/* Use one universal function and macros to reduce size */
@@ -216,7 +233,7 @@
/**
* Generic function for converting not more then @a maxlen
* hexadecimal or decimal US-ASCII digits in string to number.
- * Conversion stopped at first non-digit character or after @a maxlen
+ * Conversion stopped at first non-digit character or after @a maxlen
* digits.
* To be used only within macro.
* @param str the string to convert
@@ -230,36 +247,44 @@
* then @ max_val or @a out_val is NULL
*/
size_t
-MHD_str_to_uvalue_n_ (const char * str,
+MHD_str_to_uvalue_n_ (const char *str,
size_t maxlen,
- void * out_val,
+ void *out_val,
size_t val_size,
uint64_t max_val,
int base);
-#define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\
- sizeof(uint64_t),UINT64_MAX,10)
-
-#define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\
- sizeof(uint64_t),UINT64_MAX,10)
-
-#define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\
- sizeof(size_t),SIZE_MAX,16)
-
-#define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\
- sizeof(size_t),SIZE_MAX,16)
-
-#define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\
- sizeof(uint32_t),UINT32_MAX,16)
-
-#define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\
- sizeof(uint32_t),UINT32_MAX,16)
-
-#define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\
- sizeof(uint64_t),UINT64_MAX,16)
-
-#define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\
- sizeof(uint64_t),UINT64_MAX,16)
+#define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,10)
+
+#define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,10)
+
+#define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(size_t),SIZE_MAX, \
+ 16)
+
+#define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(size_t), \
+ SIZE_MAX,16)
+
+#define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint32_t), \
+ UINT32_MAX,16)
+
+#define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint32_t), \
+ UINT32_MAX,16)
+
+#define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,16)
+
+#define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
+ sizeof(uint64_t), \
+ UINT64_MAX,16)
#endif /* MHD_FAVOR_SMALL_CODE */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_threads.c
^
|
@@ -38,14 +38,6 @@
#include <errno.h>
-
-#if defined(MHD_USE_POSIX_THREADS)
-typedef pthread_t MHD_thread_ID_;
-#elif defined(MHD_USE_W32_THREADS)
-typedef DWORD MHD_thread_ID_;
-#endif
-
-
#ifndef MHD_USE_THREAD_NAME_
#define MHD_set_thread_name_(t, n) (void)
@@ -54,12 +46,15 @@
#else /* MHD_USE_THREAD_NAME_ */
#if defined(MHD_USE_POSIX_THREADS)
-#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
+#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
# define MHD_USE_THREAD_ATTR_SETNAME 1
-#endif /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */
+#endif \
+ /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */
-#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \
- || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
+#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
+ defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \
+ || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
/**
* Set thread name
@@ -69,25 +64,25 @@
* @return non-zero on success, zero otherwise
*/
static int
-MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
- const char *thread_name)
+MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+ const char *thread_name)
{
if (NULL == thread_name)
return 0;
#if defined(HAVE_PTHREAD_SETNAME_NP_GNU)
- return !pthread_setname_np (thread_id, thread_name);
+ return ! pthread_setname_np (thread_id, thread_name);
#elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD)
/* FreeBSD and OpenBSD use different name and void return type */
pthread_set_name_np (thread_id, thread_name);
- return !0;
+ return ! 0;
#elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
/* NetBSD use 3 arguments: second argument is string in printf-like format,
* third argument is single argument for printf;
* OSF1 use 3 arguments too, but last one always must be zero (NULL).
* MHD doesn't use '%' in thread names, so both form are used in same way.
*/
- return !pthread_setname_np (thread_id, thread_name, 0);
+ return ! pthread_setname_np (thread_id, thread_name, 0);
#endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */
}
@@ -98,10 +93,10 @@
* @param n name to set
* @return non-zero on success, zero otherwise
*/
-#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(pthread_self(),(n))
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (pthread_self (),(n))
#else /* __QNXNTO__ */
/* Special case for QNX Neutrino - using zero for thread ID sets name faster. */
-#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(0,(n))
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (0,(n))
#endif /* __QNXNTO__ */
#elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN)
@@ -110,7 +105,7 @@
* @param n name to set
* @return non-zero on success, zero otherwise
*/
-#define MHD_set_cur_thread_name_(n) (!(pthread_setname_np((n))))
+#define MHD_set_cur_thread_name_(n) (! (pthread_setname_np ((n))))
#endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */
#elif defined(MHD_USE_W32_THREADS)
@@ -125,8 +120,8 @@
* @return non-zero on success, zero otherwise
*/
static int
-MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
- const char *thread_name)
+MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
+ const char *thread_name)
{
static const DWORD VC_SETNAME_EXC = 0x406D1388;
#pragma pack(push,8)
@@ -157,7 +152,7 @@
__except (EXCEPTION_EXECUTE_HANDLER)
{}
- return !0;
+ return ! 0;
}
@@ -166,7 +161,7 @@
* @param n name to set
* @return non-zero on success, zero otherwise
*/
-#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(-1,(n))
+#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (-1,(n))
#endif /* _MSC_FULL_VER */
#endif /* MHD_USE_W32_THREADS */
@@ -183,7 +178,7 @@
* @return non-zero on success; zero otherwise (with errno set)
*/
int
-MHD_create_thread_ (MHD_thread_handle_ *thread,
+MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
size_t stack_size,
MHD_THREAD_START_ROUTINE_ start_routine,
void *arg)
@@ -192,23 +187,23 @@
int res;
if (0 != stack_size)
+ {
+ pthread_attr_t attr;
+ res = pthread_attr_init (&attr);
+ if (0 == res)
{
- pthread_attr_t attr;
- res = pthread_attr_init (&attr);
+ res = pthread_attr_setstacksize (&attr,
+ stack_size);
if (0 == res)
- {
- res = pthread_attr_setstacksize (&attr,
- stack_size);
- if (0 == res)
- res = pthread_create (thread,
- &attr,
- start_routine,
- arg);
- pthread_attr_destroy (&attr);
- }
+ res = pthread_create (&(thread->handle),
+ &attr,
+ start_routine,
+ arg);
+ pthread_attr_destroy (&attr);
}
+ }
else
- res = pthread_create (thread,
+ res = pthread_create (&(thread->handle),
NULL,
start_routine,
arg);
@@ -216,29 +211,32 @@
if (0 != res)
errno = res;
- return !res;
+ return ! res;
#elif defined(MHD_USE_W32_THREADS)
#if SIZE_MAX != UINT_MAX
if (stack_size > UINT_MAX)
- {
- errno = EINVAL;
- return 0;
- }
+ {
+ errno = EINVAL;
+ return 0;
+ }
#endif /* SIZE_MAX != UINT_MAX */
- *thread = (HANDLE) _beginthreadex (NULL,
- (unsigned int) stack_size,
- start_routine,
- arg,
- 0,
- NULL);
- if ((MHD_thread_handle_)-1 == (*thread))
+ thread->handle = (MHD_thread_handle_)
+ _beginthreadex (NULL,
+ (unsigned int) stack_size,
+ start_routine,
+ arg,
+ 0,
+ NULL);
+
+ if ((MHD_thread_handle_) - 1 == thread->handle)
return 0;
- return !0;
+ return ! 0;
#endif
}
+
#ifdef MHD_USE_THREAD_NAME_
#ifndef MHD_USE_THREAD_ATTR_SETNAME
@@ -264,22 +262,24 @@
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
named_thread_starter (void *data)
{
- struct MHD_named_helper_param_ * const param =
- (struct MHD_named_helper_param_ *) data;
- void * arg;
+ struct MHD_named_helper_param_ *const param =
+ (struct MHD_named_helper_param_ *) data;
+ void *arg;
MHD_THREAD_START_ROUTINE_ thr_func;
if (NULL == data)
- return (MHD_THRD_RTRN_TYPE_)0;
+ return (MHD_THRD_RTRN_TYPE_) 0;
MHD_set_cur_thread_name_ (param->name);
arg = param->arg;
thr_func = param->start_routine;
- free(data);
+ free (data);
- return thr_func(arg);
+ return thr_func (arg);
}
+
+
#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
@@ -294,8 +294,8 @@
* @return non-zero on success; zero otherwise (with errno set)
*/
int
-MHD_create_named_thread_ (MHD_thread_handle_ *thread,
- const char* thread_name,
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+ const char*thread_name,
size_t stack_size,
MHD_THREAD_START_ROUTINE_ start_routine,
void *arg)
@@ -306,41 +306,44 @@
res = pthread_attr_init (&attr);
if (0 == res)
- {
+ {
#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD)
- /* NetBSD use 3 arguments: second argument is string in printf-like format,
- * third argument is single argument for printf;
- * OSF1 use 3 arguments too, but last one always must be zero (NULL).
- * MHD doesn't use '%' in thread names, so both form are used in same way.
- */
- res = pthread_attr_setname_np (&attr, thread_name, 0);
+ /* NetBSD use 3 arguments: second argument is string in printf-like format,
+ * third argument is single argument for printf;
+ * OSF1 use 3 arguments too, but last one always must be zero (NULL).
+ * MHD doesn't use '%' in thread names, so both form are used in same way.
+ */
+ res = pthread_attr_setname_np (&attr,
+ thread_name,
+ 0);
#elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
- res = pthread_attr_setname_np (&attr, thread_name);
+ res = pthread_attr_setname_np (&attr,
+ thread_name);
#else
#error No pthread_attr_setname_np() function.
#endif
- if (res == 0 && 0 != stack_size)
- res = pthread_attr_setstacksize (&attr,
- stack_size);
- if (0 == res)
- res = pthread_create (thread,
- &attr,
- start_routine,
- arg);
- pthread_attr_destroy (&attr);
- }
+ if ((res == 0) && (0 != stack_size) )
+ res = pthread_attr_setstacksize (&attr,
+ stack_size);
+ if (0 == res)
+ res = pthread_create (&(thread->handle),
+ &attr,
+ start_routine,
+ arg);
+ pthread_attr_destroy (&attr);
+ }
if (0 != res)
errno = res;
- return !res;
+ return ! res;
#else /* ! MHD_USE_THREAD_ATTR_SETNAME */
struct MHD_named_helper_param_ *param;
if (NULL == thread_name)
- {
- errno = EINVAL;
- return 0;
- }
+ {
+ errno = EINVAL;
+ return 0;
+ }
param = malloc (sizeof (struct MHD_named_helper_param_));
if (NULL == param)
@@ -353,17 +356,18 @@
/* Set thread name in thread itself to avoid problems with
* threads which terminated before name is set in other thread.
*/
- if (! MHD_create_thread_(thread,
- stack_size,
- &named_thread_starter,
- (void*)param))
- {
- free (param);
- return 0;
- }
+ if (! MHD_create_thread_ (thread,
+ stack_size,
+ &named_thread_starter,
+ (void*) param))
+ {
+ free (param);
+ return 0;
+ }
- return !0;
+ return ! 0;
#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
}
+
#endif /* MHD_USE_THREAD_NAME_ */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/mhd_threads.h
^
|
@@ -47,34 +47,43 @@
# undef HAVE_CONFIG_H
# include <pthread.h>
# define HAVE_CONFIG_H 1
+# ifndef MHD_USE_THREADS
+# define MHD_USE_THREADS 1
+# endif
#elif defined(MHD_USE_W32_THREADS)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# endif /* !WIN32_LEAN_AND_MEAN */
# include <windows.h>
+# ifndef MHD_USE_THREADS
+# define MHD_USE_THREADS 1
+# endif
#else
# error No threading API is available.
#endif
#ifndef MHD_NO_THREAD_NAMES
# if defined(MHD_USE_POSIX_THREADS)
-# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
- defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
- defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
+# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
+ defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
+ defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || \
+ defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
+ defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
# define MHD_USE_THREAD_NAME_
# endif /* HAVE_PTHREAD_SETNAME_NP */
# elif defined(MHD_USE_W32_THREADS)
# ifdef _MSC_FULL_VER
- /* Thread names only available with VC compiler */
+/* Thread names only available with VC compiler */
# define MHD_USE_THREAD_NAME_
# endif /* _MSC_FULL_VER */
# endif
#endif
#if defined(MHD_USE_POSIX_THREADS)
- typedef pthread_t MHD_thread_handle_;
+typedef pthread_t MHD_thread_handle_;
#elif defined(MHD_USE_W32_THREADS)
- typedef HANDLE MHD_thread_handle_;
+typedef HANDLE MHD_thread_handle_;
#endif
#if defined(MHD_USE_POSIX_THREADS)
@@ -86,19 +95,104 @@
#endif
#if defined(MHD_USE_POSIX_THREADS)
+typedef pthread_t MHD_thread_ID_;
+#elif defined(MHD_USE_W32_THREADS)
+typedef DWORD MHD_thread_ID_;
+#endif
+
+/* Depending on implementation, pthread_create() MAY set thread ID into
+ * provided pointer and after it start thread OR start thread and after
+ * it set thread ID. In the latter case, to avoid data races, additional
+ * pthread_self() call is required in thread routine. If some platform
+ * is known for setting thread ID BEFORE starting thread macro
+ * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
+ * to save some resources. */
+/* * handle - must be valid when other thread knows that particular thread
+ is started.
+ * ID - must be valid when code is executed inside thread */
+#if defined(MHD_USE_POSIX_THREADS)
+# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+union _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+struct _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+#elif defined(MHD_USE_W32_THREADS)
+struct _MHD_thread_handle_ID_
+{
+ MHD_thread_handle_ handle; /**< To be used in other threads */
+ MHD_thread_ID_ ID; /**< To be used in thread itself */
+};
+typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
/**
* Wait until specified thread is ended and free thread handle on success.
* @param thread handle to watch
* @return nonzero on success, zero otherwise
*/
-#define MHD_join_thread_(thread) (!pthread_join((thread), NULL))
+#define MHD_join_thread_(thread) (! pthread_join ((thread), NULL))
#elif defined(MHD_USE_W32_THREADS)
/**
* Wait until specified thread is ended and free thread handle on success.
* @param thread handle to watch
* @return nonzero on success, zero otherwise
*/
-#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0)
+#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject ( \
+ (thread), INFINITE) ? (CloseHandle ( \
+ (thread)), ! 0) : \
+ 0)
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+/**
+ * Check whether provided thread ID match current thread.
+ * @param ID thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_ID_match_current_(pid) \
+ (pthread_equal ((pid).ID, pthread_self ()))
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * Check whether provided thread ID match current thread.
+ * @param ID thread ID to match
+ * @return nonzero on match, zero otherwise
+ */
+#define MHD_thread_ID_match_current_(pid) (GetCurrentThreadId () == (pid).ID)
+#endif
+
+#if defined(MHD_USE_POSIX_THREADS)
+# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) (void) 0
+# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
+ pthread_self ())
+# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
+#elif defined(MHD_USE_W32_THREADS)
+/**
+ * Initialise thread ID.
+ * @param thread_handle_ID_ptr pointer to thread handle-ID
+ */
+#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
+ GetCurrentThreadId ())
#endif
/**
@@ -114,7 +208,7 @@
/**
* Create a thread and set the attributes according to our options.
*
- * If thread is created, thread handle must be freed by #MHD_join_thread_().
+ * If thread is created, thread handle must be freed by MHD_join_thread_().
*
* @param thread handle to initialize
* @param stack_size size of stack for new thread, 0 for default
@@ -123,13 +217,13 @@
* @return non-zero on success; zero otherwise
*/
int
-MHD_create_thread_ (MHD_thread_handle_ *thread,
+MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
size_t stack_size,
MHD_THREAD_START_ROUTINE_ start_routine,
void *arg);
#ifndef MHD_USE_THREAD_NAME_
-#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a))
+#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_ ((t),(s),(r),(a))
#else /* MHD_USE_THREAD_NAME_ */
/**
* Create a named thread and set the attributes according to our options.
@@ -142,8 +236,8 @@
* @return non-zero on success; zero otherwise
*/
int
-MHD_create_named_thread_ (MHD_thread_handle_ *thread,
- const char* thread_name,
+MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
+ const char*thread_name,
size_t stack_size,
MHD_THREAD_START_ROUTINE_ start_routine,
void *arg);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/microhttpd_dll_res.rc.in
^
|
@@ -19,11 +19,11 @@
VALUE "ProductName", "GNU libmicrohttpd\0"
VALUE "ProductVersion", "@PACKAGE_VERSION@\0"
VALUE "FileVersion", "@PACKAGE_VERSION@\0"
- VALUE "FileDescription", "GNU libmicrohttpd dll for Windows (GCC build)\0"
+ VALUE "FileDescription", "GNU libmicrohttpd DLL for Windows (MinGW build)\0"
VALUE "InternalName", "libmicrohttpd\0"
- VALUE "OriginalFilename", "libmicrohttpd.dll\0"
+ VALUE "OriginalFilename", "libmicrohttpd-@MHD_W32_DLL_SUFF@.dll\0"
VALUE "CompanyName", "Free Software Foundation\0"
- VALUE "LegalCopyright", "Copyright (C) 2007-2015 Christian Grothoff and project contributors\0"
+ VALUE "LegalCopyright", "Copyright (C) 2007-2020 Christian Grothoff, Evgeny Grin and project contributors\0"
VALUE "Comments", "http://www.gnu.org/software/libmicrohttpd/\0"
END
END
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/postprocessor.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2021 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include "internal.h"
#include "mhd_str.h"
#include "mhd_compat.h"
+#include "mhd_assert.h"
/**
* Size of on-stack buffer that we use for un-escaping of the value.
@@ -47,6 +48,7 @@
/* url encoding-states */
PP_ProcessValue,
+ PP_Callback,
PP_ExpectNewLine,
/* post encoding-states */
@@ -136,8 +138,7 @@
void *cls;
/**
- * Encoding as given by the headers of the
- * connection.
+ * Encoding as given by the headers of the connection.
*/
const char *encoding;
@@ -172,10 +173,9 @@
char *content_transfer_encoding;
/**
- * Unprocessed value bytes due to escape
- * sequences (URL-encoding only).
+ * Value data left over from previous iteration.
*/
- char xbuf[8];
+ char xbuf[2];
/**
* Size of our buffer for the key.
@@ -215,7 +215,13 @@
* Used to ensure that we do always call 'ikvi' even if the
* payload is empty (but not more than once).
*/
- int must_ikvi;
+ bool must_ikvi;
+
+ /**
+ * Set if we still need to run the unescape logic
+ * on the key allocated at the end of this struct.
+ */
+ bool must_unescape_key;
/**
* State of the parser.
@@ -245,31 +251,6 @@
};
-/**
- * Create a `struct MHD_PostProcessor`.
- *
- * A `struct MHD_PostProcessor` can be used to (incrementally) parse
- * the data portion of a POST request. Note that some buggy browsers
- * fail to set the encoding type. If you want to support those, you
- * may have to call #MHD_set_connection_value with the proper encoding
- * type before creating a post processor (if no supported encoding
- * type is set, this function will fail).
- *
- * @param connection the connection on which the POST is
- * happening (used to determine the POST format)
- * @param buffer_size maximum number of bytes to use for
- * internal buffering (used only for the parsing,
- * specifically the parsing of the keys). A
- * tiny value (256-1024) should be sufficient.
- * Do NOT use a value smaller than 256. For good
- * performance, use 32 or 64k (i.e. 65536).
- * @param iter iterator to be called with the parsed data,
- * Must NOT be NULL.
- * @param iter_cls first argument to @a iter
- * @return NULL on error (out of memory, unsupported encoding),
- * otherwise a PP handle
- * @ingroup request
- */
struct MHD_PostProcessor *
MHD_create_post_processor (struct MHD_Connection *connection,
size_t buffer_size,
@@ -288,45 +269,51 @@
__FILE__,
__LINE__,
NULL);
- encoding = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_CONTENT_TYPE);
- if (NULL == encoding)
+ if (MHD_NO == MHD_lookup_connection_value_n (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_HEADER_CONTENT_TYPE),
+ &encoding,
+ NULL))
return NULL;
boundary = NULL;
if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
encoding,
- MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
+ {
+ if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
+ encoding,
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
+ return NULL;
+ boundary =
+ &encoding[MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
+ /* Q: should this be "strcasestr"? */
+ boundary = strstr (boundary, "boundary=");
+ if (NULL == boundary)
+ return NULL; /* failed to determine boundary */
+ boundary += MHD_STATICSTR_LEN_ ("boundary=");
+ blen = strlen (boundary);
+ if ( (blen == 0) ||
+ (blen * 2 + 2 > buffer_size) )
+ return NULL; /* (will be) out of memory or invalid boundary */
+ if ( (boundary[0] == '"') &&
+ (boundary[blen - 1] == '"') )
{
- if (! MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
- encoding,
- MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
- return NULL;
- boundary =
- &encoding[MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
- /* Q: should this be "strcasestr"? */
- boundary = strstr (boundary, "boundary=");
- if (NULL == boundary)
- return NULL; /* failed to determine boundary */
- boundary += MHD_STATICSTR_LEN_ ("boundary=");
- blen = strlen (boundary);
- if ( (blen == 0) ||
- (blen * 2 + 2 > buffer_size) )
- return NULL; /* (will be) out of memory or invalid boundary */
- if ( (boundary[0] == '"') &&
- (boundary[blen - 1] == '"') )
- {
- /* remove enclosing quotes */
- ++boundary;
- blen -= 2;
- }
+ /* remove enclosing quotes */
+ ++boundary;
+ blen -= 2;
}
+ }
else
blen = 0;
buffer_size += 4; /* round up to get nice block sizes despite boundary search */
/* add +1 to ensure we ALWAYS have a zero-termination at the end */
- if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor) + buffer_size + 1)))
+ if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor)
+ + buffer_size + 1)))
return NULL;
ret->connection = connection;
ret->ikvi = iter;
@@ -342,6 +329,140 @@
/**
+ * Give a (possibly partial) value to the application callback. We have some
+ * part of the value in the 'pp->xbuf', the rest is between @a value_start and
+ * @a value_end. If @a last_escape is non-NULL, there may be an incomplete
+ * escape sequence at at @a value_escape between @a value_start and @a
+ * value_end which we should preserve in 'pp->xbuf' for the future.
+ *
+ * Unescapes the value and calls the iterator together with the key. The key
+ * must already be in the key buffer allocated and 0-terminated at the end of
+ * @a pp at the time of the call.
+ *
+ * @param[in,out] pp post processor to act upon
+ * @param value_start where in memory is the value
+ * @param value_end where does the value end
+ * @param last_escape last '%'-sign in value range,
+ * if relevant, or NULL
+ */
+static void
+process_value (struct MHD_PostProcessor *pp,
+ const char *value_start,
+ const char *value_end,
+ const char *last_escape)
+{
+ char xbuf[XBUF_SIZE + 1];
+ size_t xoff;
+
+ mhd_assert (pp->xbuf_pos < sizeof (xbuf));
+ /* move remaining input from previous round into processing buffer */
+ memcpy (xbuf,
+ pp->xbuf,
+ pp->xbuf_pos);
+ xoff = pp->xbuf_pos;
+ pp->xbuf_pos = 0;
+ if ( (NULL != last_escape) &&
+ (((size_t) (value_end - last_escape)) < sizeof (pp->xbuf)) )
+ {
+ pp->xbuf_pos = value_end - last_escape;
+ memcpy (pp->xbuf,
+ last_escape,
+ value_end - last_escape);
+ value_end = last_escape;
+ }
+ while ( (value_start != value_end) ||
+ (pp->must_ikvi) ||
+ (xoff > 0) )
+ {
+ size_t delta = value_end - value_start;
+ bool cut = false;
+ size_t clen = 0;
+
+ if (delta > XBUF_SIZE - xoff)
+ delta = XBUF_SIZE - xoff;
+ /* move (additional) input into processing buffer */
+ memcpy (&xbuf[xoff],
+ value_start,
+ delta);
+ xoff += delta;
+ value_start += delta;
+ /* find if escape sequence is at the end of the processing buffer;
+ if so, exclude those from processing (reduce delta to point at
+ end of processed region) */
+ if ( (xoff > 0) &&
+ ('%' == xbuf[xoff - 1]) )
+ {
+ cut = (xoff != XBUF_SIZE);
+ xoff--;
+ if (cut)
+ {
+ /* move escape sequence into buffer for next function invocation */
+ pp->xbuf[0] = '%';
+ pp->xbuf_pos = 1;
+ }
+ else
+ {
+ /* just skip escape sequence for next loop iteration */
+ delta = xoff;
+ clen = 1;
+ }
+ }
+ else if ( (xoff > 1) &&
+ ('%' == xbuf[xoff - 2]) )
+ {
+ cut = (xoff != XBUF_SIZE);
+ xoff -= 2;
+ if (cut)
+ {
+ /* move escape sequence into buffer for next function invocation */
+ memcpy (pp->xbuf,
+ &xbuf[xoff],
+ 2);
+ pp->xbuf_pos = 2;
+ }
+ else
+ {
+ /* just skip escape sequence for next loop iteration */
+ delta = xoff;
+ clen = 2;
+ }
+ }
+ mhd_assert (xoff < sizeof (xbuf));
+ /* unescape */
+ xbuf[xoff] = '\0'; /* 0-terminate in preparation */
+ MHD_unescape_plus (xbuf);
+ xoff = MHD_http_unescape (xbuf);
+ /* finally: call application! */
+ if (pp->must_ikvi || (0 != xoff) )
+ {
+ pp->must_ikvi = false;
+ if (MHD_NO == pp->ikvi (pp->cls,
+ MHD_POSTDATA_KIND,
+ (const char *) &pp[1], /* key */
+ NULL,
+ NULL,
+ NULL,
+ xbuf,
+ pp->value_offset,
+ xoff))
+ {
+ pp->state = PP_Error;
+ return;
+ }
+ }
+ pp->value_offset += xoff;
+ if (cut)
+ break;
+ xbuf[delta] = '%'; /* undo 0-termination */
+ memmove (xbuf,
+ &xbuf[delta],
+ clen);
+ xoff = clen;
+ }
+}
+
+
+/**
* Process url-encoded POST data.
*
* @param pp post processor context
@@ -352,163 +473,225 @@
static int
post_process_urlencoded (struct MHD_PostProcessor *pp,
const char *post_data,
- size_t post_data_len)
+ size_t post_data_len)
{
- size_t equals;
- size_t amper;
+ char *kbuf = (char *) &pp[1];
size_t poff;
- size_t xoff;
- size_t delta;
- int end_of_value_found;
- char *buf;
- char xbuf[XBUF_SIZE + 1];
+ const char *start_key = NULL;
+ const char *end_key = NULL;
+ const char *start_value = NULL;
+ const char *end_value = NULL;
+ const char *last_escape = NULL;
+
+ mhd_assert (PP_Callback != pp->state);
- buf = (char *) &pp[1];
poff = 0;
- while (poff < post_data_len)
+ while ( ( (poff < post_data_len) ||
+ (pp->state == PP_Callback) ) &&
+ (pp->state != PP_Error) )
+ {
+ switch (pp->state)
{
- switch (pp->state)
+ case PP_Error:
+ /* clearly impossible as per while loop invariant */
+ abort ();
+ break;
+ case PP_Init:
+ /* key phase */
+ if (NULL == start_key)
+ start_key = &post_data[poff];
+ pp->must_ikvi = true;
+ switch (post_data[poff])
+ {
+ case '=':
+ /* Case: 'key=' */
+ end_key = &post_data[poff];
+ poff++;
+ pp->state = PP_ProcessValue;
+ break;
+ case '&':
+ /* Case: 'key&' */
+ end_key = &post_data[poff];
+ mhd_assert (NULL == start_value);
+ mhd_assert (NULL == end_value);
+ poff++;
+ pp->state = PP_Callback;
+ break;
+ case '\n':
+ case '\r':
+ /* Case: 'key\n' or 'key\r' */
+ end_key = &post_data[poff];
+ poff++;
+ pp->state = PP_Done;
+ break;
+ default:
+ /* normal character, advance! */
+ poff++;
+ continue;
+ }
+ break; /* end PP_Init */
+ case PP_ProcessValue:
+ if (NULL == start_value)
+ start_value = &post_data[poff];
+ switch (post_data[poff])
+ {
+ case '=':
+ /* case 'key==' */
+ pp->state = PP_Error;
+ continue;
+ case '&':
+ /* case 'value&' */
+ end_value = &post_data[poff];
+ poff++;
+ if (pp->must_ikvi ||
+ (start_value != end_value) )
{
- case PP_Error:
- return MHD_NO;
- case PP_Done:
- /* did not expect to receive more data */
- pp->state = PP_Error;
- return MHD_NO;
- case PP_Init:
- equals = 0;
- while ((equals + poff < post_data_len) &&
- (post_data[equals + poff] != '='))
- equals++;
- if (equals + pp->buffer_pos > pp->buffer_size)
- {
- pp->state = PP_Error; /* out of memory */
- return MHD_NO;
- }
- memcpy (&buf[pp->buffer_pos], &post_data[poff], equals);
- pp->buffer_pos += equals;
- if (equals + poff == post_data_len)
- return MHD_YES; /* no '=' yet */
- buf[pp->buffer_pos] = '\0'; /* 0-terminate key */
- pp->buffer_pos = 0; /* reset for next key */
- MHD_unescape_plus (buf);
- MHD_http_unescape (buf);
- poff += equals + 1;
- pp->state = PP_ProcessValue;
+ pp->state = PP_Callback;
+ }
+ else
+ {
+ pp->buffer_pos = 0;
pp->value_offset = 0;
- break;
- case PP_ProcessValue:
- /* obtain rest of value from previous iteration */
- memcpy (xbuf, pp->xbuf, pp->xbuf_pos);
- xoff = pp->xbuf_pos;
- pp->xbuf_pos = 0;
-
- /* find last position in input buffer that is part of the value */
- amper = 0;
- while ((amper + poff < post_data_len) &&
- (amper < XBUF_SIZE) &&
- (post_data[amper + poff] != '&') &&
- (post_data[amper + poff] != '\n') &&
- (post_data[amper + poff] != '\r'))
- amper++;
- end_of_value_found = ((amper + poff < post_data_len) &&
- ((post_data[amper + poff] == '&') ||
- (post_data[amper + poff] == '\n') ||
- (post_data[amper + poff] == '\r')));
- /* compute delta, the maximum number of bytes that we will be able to
- process right now (either amper-limited of xbuf-size limited) */
- delta = amper;
- if (delta > XBUF_SIZE - xoff)
- delta = XBUF_SIZE - xoff;
-
- /* move input into processing buffer */
- memcpy (&xbuf[xoff], &post_data[poff], delta);
- xoff += delta;
- poff += delta;
-
- /* find if escape sequence is at the end of the processing buffer;
- if so, exclude those from processing (reduce delta to point at
- end of processed region) */
- delta = xoff;
- if ((delta > 0) &&
- ('%' == xbuf[delta - 1]))
- delta--;
- else if ((delta > 1) &&
- ('%' == xbuf[delta - 2]))
- delta -= 2;
-
- /* if we have an incomplete escape sequence, save it to
- pp->xbuf for later */
- if (delta < xoff)
- {
- memcpy (pp->xbuf,
- &xbuf[delta],
- xoff - delta);
- pp->xbuf_pos = xoff - delta;
- xoff = delta;
- }
-
- /* If we have nothing to do (delta == 0) and
- not just because the value is empty (are
- waiting for more data), go for next iteration */
- if ( (0 == xoff) &&
- (poff == post_data_len))
- continue;
-
- /* unescape */
- xbuf[xoff] = '\0'; /* 0-terminate in preparation */
- MHD_unescape_plus (xbuf);
- xoff = MHD_http_unescape (xbuf);
- /* finally: call application! */
- pp->must_ikvi = MHD_NO;
- if (MHD_NO == pp->ikvi (pp->cls,
- MHD_POSTDATA_KIND,
- (const char *) &pp[1], /* key */
- NULL,
- NULL,
- NULL,
- xbuf,
- pp->value_offset,
- xoff))
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- pp->value_offset += xoff;
-
- /* are we done with the value? */
- if (end_of_value_found)
- {
- /* we found the end of the value! */
- if ( ('\n' == post_data[poff]) ||
- ('\r' == post_data[poff]) )
- {
- pp->state = PP_ExpectNewLine;
- }
- else if ('&' == post_data[poff])
- {
- poff++; /* skip '&' */
- pp->state = PP_Init;
- }
- }
- break;
- case PP_ExpectNewLine:
- if ( ('\n' == post_data[poff]) ||
- ('\r' == post_data[poff]) )
- {
- poff++;
- /* we are done, report error if we receive any more... */
- pp->state = PP_Done;
- return MHD_YES;
- }
- return MHD_NO;
- default:
- mhd_panic (mhd_panic_cls,
- __FILE__,
- __LINE__,
- NULL); /* should never happen! */
+ pp->state = PP_Init;
+ start_value = NULL;
+ end_value = NULL;
}
+ continue;
+ case '\n':
+ case '\r':
+ /* Case: 'value\n' or 'value\r' */
+ end_value = &post_data[poff];
+ poff++;
+ if (pp->must_ikvi)
+ pp->state = PP_Callback;
+ else
+ pp->state = PP_Done;
+ break;
+ case '%':
+ last_escape = &post_data[poff];
+ poff++;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* character, may be part of escaping */
+ poff++;
+ continue;
+ default:
+ /* normal character, no more escaping! */
+ last_escape = NULL;
+ poff++;
+ continue;
+ }
+ break; /* end PP_ProcessValue */
+ case PP_Done:
+ switch (post_data[poff])
+ {
+ case '\n':
+ case '\r':
+ poff++;
+ continue;
+ }
+ /* unexpected data at the end, fail! */
+ pp->state = PP_Error;
+ break;
+ case PP_Callback:
+ if ( (pp->buffer_pos + (end_key - start_key) >=
+ pp->buffer_size) ||
+ (pp->buffer_pos + (end_key - start_key) <
+ pp->buffer_pos) )
+ {
+ /* key too long, cannot parse! */
+ pp->state = PP_Error;
+ continue;
+ }
+ /* compute key, if we have not already */
+ if (NULL != start_key)
+ {
+ memcpy (&kbuf[pp->buffer_pos],
+ start_key,
+ end_key - start_key);
+ pp->buffer_pos += end_key - start_key;
+ start_key = NULL;
+ end_key = NULL;
+ pp->must_unescape_key = true;
+ }
+ if (pp->must_unescape_key)
+ {
+ kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
+ MHD_unescape_plus (kbuf);
+ MHD_http_unescape (kbuf);
+ pp->must_unescape_key = false;
+ }
+ process_value (pp,
+ start_value,
+ end_value,
+ NULL);
+ if (PP_Error == pp->state)
+ continue;
+ pp->value_offset = 0;
+ start_value = NULL;
+ end_value = NULL;
+ pp->buffer_pos = 0;
+ pp->state = PP_Init;
+ break;
+ default:
+ mhd_panic (mhd_panic_cls,
+ __FILE__,
+ __LINE__,
+ NULL); /* should never happen! */
}
+ }
+
+ /* save remaining data for next iteration */
+ if (NULL != start_key)
+ {
+ if (NULL == end_key)
+ end_key = &post_data[poff];
+ if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size)
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ memcpy (&kbuf[pp->buffer_pos],
+ start_key,
+ end_key - start_key);
+ pp->buffer_pos += end_key - start_key;
+ pp->must_unescape_key = true;
+ start_key = NULL;
+ end_key = NULL;
+ }
+ if ( (NULL != start_value) &&
+ (PP_ProcessValue == pp->state) )
+ {
+ /* compute key, if we have not already */
+ if (pp->must_unescape_key)
+ {
+ kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
+ MHD_unescape_plus (kbuf);
+ MHD_http_unescape (kbuf);
+ pp->must_unescape_key = false;
+ }
+ if (NULL == end_value)
+ end_value = &post_data[poff];
+ process_value (pp,
+ start_value,
+ end_value,
+ last_escape);
+ pp->must_ikvi = false;
+ }
+ if (PP_Error == pp->state)
+ {
+ /* State in error, returning failure */
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -518,28 +701,30 @@
* rest of the line into the suffix ptr.
*
* @param prefix prefix to match
+ * @param prefix_len length of @a prefix
* @param line line to match prefix in
* @param suffix set to a copy of the rest of the line, starting at the end of the match
* @return #MHD_YES if there was a match, #MHD_NO if not
*/
static int
try_match_header (const char *prefix,
+ size_t prefix_len,
char *line,
char **suffix)
{
if (NULL != *suffix)
return MHD_NO;
while (0 != *line)
+ {
+ if (MHD_str_equal_caseless_n_ (prefix,
+ line,
+ prefix_len))
{
- if (MHD_str_equal_caseless_n_ (prefix,
- line,
- strlen (prefix)))
- {
- *suffix = strdup (&line[strlen (prefix)]);
- return MHD_YES;
- }
- ++line;
+ *suffix = strdup (&line[prefix_len]);
+ return MHD_YES;
}
+ ++line;
+ }
return MHD_NO;
}
@@ -569,40 +754,39 @@
const char *dash;
if (pp->buffer_pos < 2 + blen)
- {
- if (pp->buffer_pos == pp->buffer_size)
- pp->state = PP_Error; /* out of memory */
- /* ++(*ioffptr); */
- return MHD_NO; /* not enough data */
- }
+ {
+ if (pp->buffer_pos == pp->buffer_size)
+ pp->state = PP_Error; /* out of memory */
+ /* ++(*ioffptr); */
+ return MHD_NO; /* not enough data */
+ }
if ( (0 != memcmp ("--",
buf,
2)) ||
(0 != memcmp (&buf[2],
boundary,
blen)))
+ {
+ if (pp->state != PP_Init)
{
- if (pp->state != PP_Init)
- {
- /* garbage not allowed */
- pp->state = PP_Error;
- }
+ /* garbage not allowed */
+ pp->state = PP_Error;
+ }
+ else
+ {
+ /* skip over garbage (RFC 2046, 5.1.1) */
+ dash = memchr (buf,
+ '-',
+ pp->buffer_pos);
+ if (NULL == dash)
+ (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
+ else if (dash == buf)
+ (*ioffptr)++; /* at least skip one byte */
else
- {
- /* skip over garbage (RFC 2046, 5.1.1) */
- dash = memchr (buf,
- '-',
- pp->buffer_pos);
- if (NULL == dash)
- (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
- else
- if (dash == buf)
- (*ioffptr)++; /* at least skip one byte */
- else
- (*ioffptr) += dash - buf; /* skip to first possible boundary */
- }
- return MHD_NO; /* expected boundary */
+ (*ioffptr) += dash - buf; /* skip to first possible boundary */
}
+ return MHD_NO; /* expected boundary */
+ }
/* remove boundary from buffer */
(*ioffptr) += 2 + blen;
/* next: start with headers */
@@ -621,8 +805,8 @@
*/
static void
try_get_value (const char *buf,
- const char *key,
- char **destination)
+ const char *key,
+ char **destination)
{
const char *spos;
const char *bpos;
@@ -635,30 +819,30 @@
bpos = buf;
klen = strlen (key);
while (NULL != (spos = strstr (bpos, key)))
+ {
+ if ( (spos[klen] != '=') ||
+ ( (spos != buf) &&
+ (spos[-1] != ' ') ) )
{
- if ( (spos[klen] != '=') ||
- ( (spos != buf) &&
- (spos[-1] != ' ') ) )
- {
- /* no match */
- bpos = spos + 1;
- continue;
- }
- if (spos[klen + 1] != '"')
- return; /* not quoted */
- if (NULL == (endv = strchr (&spos[klen + 2],
- '\"')))
- return; /* no end-quote */
- vlen = endv - spos - klen - 1;
- *destination = malloc (vlen);
- if (NULL == *destination)
- return; /* out of memory */
- (*destination)[vlen - 1] = '\0';
- memcpy (*destination,
- &spos[klen + 2],
- vlen - 1);
- return; /* success */
+ /* no match */
+ bpos = spos + 1;
+ continue;
}
+ if (spos[klen + 1] != '"')
+ return; /* not quoted */
+ if (NULL == (endv = strchr (&spos[klen + 2],
+ '\"')))
+ return; /* no end-quote */
+ vlen = endv - spos - klen - 1;
+ *destination = malloc (vlen);
+ if (NULL == *destination)
+ return; /* out of memory */
+ (*destination)[vlen - 1] = '\0';
+ memcpy (*destination,
+ &spos[klen + 2],
+ vlen - 1);
+ return; /* success */
+ }
}
@@ -691,19 +875,19 @@
(buf[newline] != '\n') )
newline++;
if (newline == pp->buffer_size)
- {
- pp->state = PP_Error;
- return MHD_NO; /* out of memory */
- }
+ {
+ pp->state = PP_Error;
+ return MHD_NO; /* out of memory */
+ }
if (newline == pp->buffer_pos)
return MHD_NO; /* will need more data */
if (0 == newline)
- {
- /* empty line - end of headers */
- pp->skip_rn = RN_Full;
- pp->state = next_state;
- return MHD_YES;
- }
+ {
+ /* empty line - end of headers */
+ pp->skip_rn = RN_Full;
+ pp->state = next_state;
+ return MHD_YES;
+ }
/* got an actual header */
if (buf[newline] == '\r')
pp->skip_rn = RN_OptN;
@@ -711,23 +895,25 @@
if (MHD_str_equal_caseless_n_ ("Content-disposition: ",
buf,
MHD_STATICSTR_LEN_ ("Content-disposition: ")))
- {
- try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
- "name",
- &pp->content_name);
- try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
- "filename",
- &pp->content_filename);
- }
+ {
+ try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
+ "name",
+ &pp->content_name);
+ try_get_value (&buf[MHD_STATICSTR_LEN_ ("Content-disposition: ")],
+ "filename",
+ &pp->content_filename);
+ }
else
- {
- try_match_header ("Content-type: ",
- buf,
- &pp->content_type);
- try_match_header ("Content-Transfer-Encoding: ",
- buf,
- &pp->content_transfer_encoding);
- }
+ {
+ try_match_header ("Content-type: ",
+ MHD_STATICSTR_LEN_ ("Content-type: "),
+ buf,
+ &pp->content_type);
+ try_match_header ("Content-Transfer-Encoding: ",
+ MHD_STATICSTR_LEN_ ("Content-Transfer-Encoding: "),
+ buf,
+ &pp->content_transfer_encoding);
+ }
(*ioffptr) += newline + 1;
return MHD_YES;
}
@@ -765,80 +951,80 @@
(\r\n--+boundary) is part of the value */
newline = 0;
while (1)
+ {
+ while (newline + 4 < pp->buffer_pos)
{
- while (newline + 4 < pp->buffer_pos)
- {
- r = memchr (&buf[newline],
- '\r',
- pp->buffer_pos - newline - 4);
- if (NULL == r)
- {
- newline = pp->buffer_pos - 4;
- break;
- }
- newline = r - buf;
- if (0 == memcmp ("\r\n--",
- &buf[newline],
- 4))
- break;
- newline++;
- }
- if (newline + pp->blen + 4 <= pp->buffer_pos)
- {
- /* can check boundary */
- if (0 != memcmp (&buf[newline + 4],
- boundary,
- pp->blen))
- {
- /* no boundary, "\r\n--" is part of content, skip */
- newline += 4;
- continue;
- }
- else
- {
- /* boundary found, process until newline then
- skip boundary and go back to init */
- pp->skip_rn = RN_Dash;
- pp->state = next_state;
- pp->dash_state = next_dash_state;
- (*ioffptr) += pp->blen + 4; /* skip boundary as well */
- buf[newline] = '\0';
- break;
- }
- }
+ r = memchr (&buf[newline],
+ '\r',
+ pp->buffer_pos - newline - 4);
+ if (NULL == r)
+ {
+ newline = pp->buffer_pos - 4;
+ break;
+ }
+ newline = r - buf;
+ if (0 == memcmp ("\r\n--",
+ &buf[newline],
+ 4))
+ break;
+ newline++;
+ }
+ if (newline + blen + 4 <= pp->buffer_pos)
+ {
+ /* can check boundary */
+ if (0 != memcmp (&buf[newline + 4],
+ boundary,
+ blen))
+ {
+ /* no boundary, "\r\n--" is part of content, skip */
+ newline += 4;
+ continue;
+ }
else
- {
- /* cannot check for boundary, process content that
- we have and check again later; except, if we have
- no content, abort (out of memory) */
- if ( (0 == newline) &&
- (pp->buffer_pos == pp->buffer_size) )
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- break;
- }
+ {
+ /* boundary found, process until newline then
+ skip boundary and go back to init */
+ pp->skip_rn = RN_Dash;
+ pp->state = next_state;
+ pp->dash_state = next_dash_state;
+ (*ioffptr) += blen + 4; /* skip boundary as well */
+ buf[newline] = '\0';
+ break;
+ }
+ }
+ else
+ {
+ /* cannot check for boundary, process content that
+ we have and check again later; except, if we have
+ no content, abort (out of memory) */
+ if ( (0 == newline) &&
+ (pp->buffer_pos == pp->buffer_size) )
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ break;
}
+ }
/* newline is either at beginning of boundary or
at least at the last character that we are sure
is not part of the boundary */
- if ( ( (MHD_YES == pp->must_ikvi) ||
- (0 != newline) ) &&
+ if ( ( (pp->must_ikvi) ||
+ (0 != newline) ) &&
(MHD_NO == pp->ikvi (pp->cls,
- MHD_POSTDATA_KIND,
- pp->content_name,
- pp->content_filename,
- pp->content_type,
- pp->content_transfer_encoding,
- buf,
+ MHD_POSTDATA_KIND,
+ pp->content_name,
+ pp->content_filename,
+ pp->content_type,
+ pp->content_transfer_encoding,
+ buf,
pp->value_offset,
newline)) )
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- pp->must_ikvi = MHD_NO;
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ pp->must_ikvi = false;
pp->value_offset += newline;
(*ioffptr) += newline;
return MHD_YES;
@@ -854,28 +1040,28 @@
{
if ( (NULL != pp->content_name) &&
(0 == (pp->have & NE_content_name)) )
- {
- free (pp->content_name);
- pp->content_name = NULL;
- }
+ {
+ free (pp->content_name);
+ pp->content_name = NULL;
+ }
if ( (NULL != pp->content_type) &&
(0 == (pp->have & NE_content_type)) )
- {
- free (pp->content_type);
- pp->content_type = NULL;
- }
+ {
+ free (pp->content_type);
+ pp->content_type = NULL;
+ }
if ( (NULL != pp->content_filename) &&
(0 == (pp->have & NE_content_filename)) )
- {
- free (pp->content_filename);
- pp->content_filename = NULL;
- }
+ {
+ free (pp->content_filename);
+ pp->content_filename = NULL;
+ }
if ( (NULL != pp->content_transfer_encoding) &&
(0 == (pp->have & NE_content_transfer_encoding)) )
- {
- free (pp->content_transfer_encoding);
- pp->content_transfer_encoding = NULL;
- }
+ {
+ free (pp->content_transfer_encoding);
+ pp->content_transfer_encoding = NULL;
+ }
}
@@ -890,7 +1076,7 @@
static int
post_process_multipart (struct MHD_PostProcessor *pp,
const char *post_data,
- size_t post_data_len)
+ size_t post_data_len)
{
char *buf;
size_t max;
@@ -905,312 +1091,299 @@
while ( (poff < post_data_len) ||
( (pp->buffer_pos > 0) &&
(0 != state_changed) ) )
+ {
+ /* first, move as much input data
+ as possible to our internal buffer */
+ max = pp->buffer_size - pp->buffer_pos;
+ if (max > post_data_len - poff)
+ max = post_data_len - poff;
+ memcpy (&buf[pp->buffer_pos],
+ &post_data[poff],
+ max);
+ poff += max;
+ pp->buffer_pos += max;
+ if ( (0 == max) &&
+ (0 == state_changed) &&
+ (poff < post_data_len) )
{
- /* first, move as much input data
- as possible to our internal buffer */
- max = pp->buffer_size - pp->buffer_pos;
- if (max > post_data_len - poff)
- max = post_data_len - poff;
- memcpy (&buf[pp->buffer_pos],
- &post_data[poff],
- max);
- poff += max;
- pp->buffer_pos += max;
- if ( (0 == max) &&
- (0 == state_changed) &&
- (poff < post_data_len) )
- {
- pp->state = PP_Error;
- return MHD_NO; /* out of memory */
- }
- state_changed = 0;
+ pp->state = PP_Error;
+ return MHD_NO; /* out of memory */
+ }
+ state_changed = 0;
- /* first state machine for '\r'-'\n' and '--' handling */
- switch (pp->skip_rn)
+ /* first state machine for '\r'-'\n' and '--' handling */
+ switch (pp->skip_rn)
+ {
+ case RN_Inactive:
+ break;
+ case RN_OptN:
+ if (buf[0] == '\n')
+ {
+ ioff++;
+ pp->skip_rn = RN_Inactive;
+ goto AGAIN;
+ }
+ /* fall-through! */
+ case RN_Dash:
+ if (buf[0] == '-')
+ {
+ ioff++;
+ pp->skip_rn = RN_Dash2;
+ goto AGAIN;
+ }
+ pp->skip_rn = RN_Full;
+ /* fall-through! */
+ case RN_Full:
+ if (buf[0] == '\r')
+ {
+ if ( (pp->buffer_pos > 1) &&
+ ('\n' == buf[1]) )
{
- case RN_Inactive:
- break;
- case RN_OptN:
- if (buf[0] == '\n')
- {
- ioff++;
- pp->skip_rn = RN_Inactive;
- goto AGAIN;
- }
- /* fall-through! */
- case RN_Dash:
- if (buf[0] == '-')
- {
- ioff++;
- pp->skip_rn = RN_Dash2;
- goto AGAIN;
- }
- pp->skip_rn = RN_Full;
- /* fall-through! */
- case RN_Full:
- if (buf[0] == '\r')
- {
- if ( (pp->buffer_pos > 1) &&
- ('\n' == buf[1]) )
- {
- pp->skip_rn = RN_Inactive;
- ioff += 2;
- }
- else
- {
- pp->skip_rn = RN_OptN;
- ioff++;
- }
- goto AGAIN;
- }
- if (buf[0] == '\n')
- {
- ioff++;
- pp->skip_rn = RN_Inactive;
- goto AGAIN;
- }
pp->skip_rn = RN_Inactive;
- pp->state = PP_Error;
- return MHD_NO; /* no '\r\n' */
- case RN_Dash2:
- if (buf[0] == '-')
- {
- ioff++;
- pp->skip_rn = RN_Full;
- pp->state = pp->dash_state;
- goto AGAIN;
- }
- pp->state = PP_Error;
- break;
+ ioff += 2;
}
-
- /* main state engine */
- switch (pp->state)
+ else
{
- case PP_Error:
+ pp->skip_rn = RN_OptN;
+ ioff++;
+ }
+ goto AGAIN;
+ }
+ if (buf[0] == '\n')
+ {
+ ioff++;
+ pp->skip_rn = RN_Inactive;
+ goto AGAIN;
+ }
+ pp->skip_rn = RN_Inactive;
+ pp->state = PP_Error;
+ return MHD_NO; /* no '\r\n' */
+ case RN_Dash2:
+ if (buf[0] == '-')
+ {
+ ioff++;
+ pp->skip_rn = RN_Full;
+ pp->state = pp->dash_state;
+ goto AGAIN;
+ }
+ pp->state = PP_Error;
+ break;
+ }
+
+ /* main state engine */
+ switch (pp->state)
+ {
+ case PP_Error:
+ return MHD_NO;
+ case PP_Done:
+ /* did not expect to receive more data */
+ pp->state = PP_Error;
+ return MHD_NO;
+ case PP_Init:
+ /**
+ * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
+ * prior to the first multipart boundary:
+ *
+ * > There appears to be room for additional information prior
+ * > to the first boundary delimiter line and following the
+ * > final boundary delimiter line. These areas should
+ * > generally be left blank, and implementations must ignore
+ * > anything that appears before the first boundary delimiter
+ * > line or after the last one.
+ */
+ (void) find_boundary (pp,
+ pp->boundary,
+ pp->blen,
+ &ioff,
+ PP_ProcessEntryHeaders,
+ PP_Done);
+ break;
+ case PP_NextBoundary:
+ if (MHD_NO == find_boundary (pp,
+ pp->boundary,
+ pp->blen,
+ &ioff,
+ PP_ProcessEntryHeaders,
+ PP_Done))
+ {
+ if (pp->state == PP_Error)
return MHD_NO;
- case PP_Done:
- /* did not expect to receive more data */
+ goto END;
+ }
+ break;
+ case PP_ProcessEntryHeaders:
+ pp->must_ikvi = true;
+ if (MHD_NO ==
+ process_multipart_headers (pp,
+ &ioff,
+ PP_PerformCheckMultipart))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ else
+ goto END;
+ }
+ state_changed = 1;
+ break;
+ case PP_PerformCheckMultipart:
+ if ( (NULL != pp->content_type) &&
+ (MHD_str_equal_caseless_n_ (pp->content_type,
+ "multipart/mixed",
+ MHD_STATICSTR_LEN_ ("multipart/mixed"))))
+ {
+ pp->nested_boundary = strstr (pp->content_type,
+ "boundary=");
+ if (NULL == pp->nested_boundary)
+ {
pp->state = PP_Error;
return MHD_NO;
- case PP_Init:
- /**
- * Per RFC2046 5.1.1 NOTE TO IMPLEMENTORS, consume anything
- * prior to the first multipart boundary:
- *
- * > There appears to be room for additional information prior
- * > to the first boundary delimiter line and following the
- * > final boundary delimiter line. These areas should
- * > generally be left blank, and implementations must ignore
- * > anything that appears before the first boundary delimiter
- * > line or after the last one.
- */
- (void) find_boundary (pp,
- pp->boundary,
- pp->blen,
- &ioff,
- PP_ProcessEntryHeaders,
- PP_Done);
- break;
- case PP_NextBoundary:
- if (MHD_NO == find_boundary (pp,
- pp->boundary,
- pp->blen,
- &ioff,
- PP_ProcessEntryHeaders,
- PP_Done))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- goto END;
- }
- break;
- case PP_ProcessEntryHeaders:
- pp->must_ikvi = MHD_YES;
- if (MHD_NO ==
- process_multipart_headers (pp,
- &ioff,
- PP_PerformCheckMultipart))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- else
- goto END;
- }
- state_changed = 1;
- break;
- case PP_PerformCheckMultipart:
- if ( (NULL != pp->content_type) &&
- (MHD_str_equal_caseless_n_ (pp->content_type,
- "multipart/mixed",
- MHD_STATICSTR_LEN_ ("multipart/mixed"))))
- {
- pp->nested_boundary = strstr (pp->content_type,
- "boundary=");
- if (NULL == pp->nested_boundary)
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- pp->nested_boundary =
- strdup (&pp->nested_boundary[MHD_STATICSTR_LEN_ ("boundary=")]);
- if (NULL == pp->nested_boundary)
- {
- /* out of memory */
- pp->state = PP_Error;
- return MHD_NO;
- }
- /* free old content type, we will need that field
- for the content type of the nested elements */
- free (pp->content_type);
- pp->content_type = NULL;
- pp->nlen = strlen (pp->nested_boundary);
- pp->state = PP_Nested_Init;
- state_changed = 1;
- break;
- }
- pp->state = PP_ProcessValueToBoundary;
- pp->value_offset = 0;
- state_changed = 1;
- break;
- case PP_ProcessValueToBoundary:
- if (MHD_NO == process_value_to_boundary (pp,
- &ioff,
- pp->boundary,
- pp->blen,
- PP_PerformCleanup,
- PP_Done))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- break;
- }
- break;
- case PP_PerformCleanup:
- /* clean up state of one multipart form-data element! */
- pp->have = NE_none;
- free_unmarked (pp);
- if (NULL != pp->nested_boundary)
- {
- free (pp->nested_boundary);
- pp->nested_boundary = NULL;
- }
- pp->state = PP_ProcessEntryHeaders;
- state_changed = 1;
- break;
- case PP_Nested_Init:
- if (NULL == pp->nested_boundary)
- {
- pp->state = PP_Error;
- return MHD_NO;
- }
- if (MHD_NO == find_boundary (pp,
- pp->nested_boundary,
- pp->nlen,
- &ioff,
- PP_Nested_PerformMarking,
- PP_NextBoundary /* or PP_Error? */ ))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- goto END;
- }
- break;
- case PP_Nested_PerformMarking:
- /* remember what headers were given
- globally */
- pp->have = NE_none;
- if (NULL != pp->content_name)
- pp->have |= NE_content_name;
- if (NULL != pp->content_type)
- pp->have |= NE_content_type;
- if (NULL != pp->content_filename)
- pp->have |= NE_content_filename;
- if (NULL != pp->content_transfer_encoding)
- pp->have |= NE_content_transfer_encoding;
- pp->state = PP_Nested_ProcessEntryHeaders;
- state_changed = 1;
- break;
- case PP_Nested_ProcessEntryHeaders:
- pp->value_offset = 0;
- if (MHD_NO ==
- process_multipart_headers (pp,
- &ioff,
- PP_Nested_ProcessValueToBoundary))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- else
- goto END;
- }
- state_changed = 1;
- break;
- case PP_Nested_ProcessValueToBoundary:
- if (MHD_NO == process_value_to_boundary (pp,
- &ioff,
- pp->nested_boundary,
- pp->nlen,
- PP_Nested_PerformCleanup,
- PP_NextBoundary))
- {
- if (pp->state == PP_Error)
- return MHD_NO;
- break;
- }
- break;
- case PP_Nested_PerformCleanup:
- free_unmarked (pp);
- pp->state = PP_Nested_ProcessEntryHeaders;
- state_changed = 1;
- break;
- default:
- mhd_panic (mhd_panic_cls,
- __FILE__,
- __LINE__,
- NULL); /* should never happen! */
}
- AGAIN:
- if (ioff > 0)
+ pp->nested_boundary =
+ strdup (&pp->nested_boundary[MHD_STATICSTR_LEN_ ("boundary=")]);
+ if (NULL == pp->nested_boundary)
{
- memmove (buf,
- &buf[ioff],
- pp->buffer_pos - ioff);
- pp->buffer_pos -= ioff;
- ioff = 0;
- state_changed = 1;
+ /* out of memory */
+ pp->state = PP_Error;
+ return MHD_NO;
}
+ /* free old content type, we will need that field
+ for the content type of the nested elements */
+ free (pp->content_type);
+ pp->content_type = NULL;
+ pp->nlen = strlen (pp->nested_boundary);
+ pp->state = PP_Nested_Init;
+ state_changed = 1;
+ break;
+ }
+ pp->state = PP_ProcessValueToBoundary;
+ pp->value_offset = 0;
+ state_changed = 1;
+ break;
+ case PP_ProcessValueToBoundary:
+ if (MHD_NO == process_value_to_boundary (pp,
+ &ioff,
+ pp->boundary,
+ pp->blen,
+ PP_PerformCleanup,
+ PP_Done))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ break;
+ }
+ break;
+ case PP_PerformCleanup:
+ /* clean up state of one multipart form-data element! */
+ pp->have = NE_none;
+ free_unmarked (pp);
+ if (NULL != pp->nested_boundary)
+ {
+ free (pp->nested_boundary);
+ pp->nested_boundary = NULL;
+ }
+ pp->state = PP_ProcessEntryHeaders;
+ state_changed = 1;
+ break;
+ case PP_Nested_Init:
+ if (NULL == pp->nested_boundary)
+ {
+ pp->state = PP_Error;
+ return MHD_NO;
+ }
+ if (MHD_NO == find_boundary (pp,
+ pp->nested_boundary,
+ pp->nlen,
+ &ioff,
+ PP_Nested_PerformMarking,
+ PP_NextBoundary /* or PP_Error? */))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ goto END;
+ }
+ break;
+ case PP_Nested_PerformMarking:
+ /* remember what headers were given
+ globally */
+ pp->have = NE_none;
+ if (NULL != pp->content_name)
+ pp->have |= NE_content_name;
+ if (NULL != pp->content_type)
+ pp->have |= NE_content_type;
+ if (NULL != pp->content_filename)
+ pp->have |= NE_content_filename;
+ if (NULL != pp->content_transfer_encoding)
+ pp->have |= NE_content_transfer_encoding;
+ pp->state = PP_Nested_ProcessEntryHeaders;
+ state_changed = 1;
+ break;
+ case PP_Nested_ProcessEntryHeaders:
+ pp->value_offset = 0;
+ if (MHD_NO ==
+ process_multipart_headers (pp,
+ &ioff,
+ PP_Nested_ProcessValueToBoundary))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ else
+ goto END;
+ }
+ state_changed = 1;
+ break;
+ case PP_Nested_ProcessValueToBoundary:
+ if (MHD_NO == process_value_to_boundary (pp,
+ &ioff,
+ pp->nested_boundary,
+ pp->nlen,
+ PP_Nested_PerformCleanup,
+ PP_NextBoundary))
+ {
+ if (pp->state == PP_Error)
+ return MHD_NO;
+ break;
+ }
+ break;
+ case PP_Nested_PerformCleanup:
+ free_unmarked (pp);
+ pp->state = PP_Nested_ProcessEntryHeaders;
+ state_changed = 1;
+ break;
+ default:
+ mhd_panic (mhd_panic_cls,
+ __FILE__,
+ __LINE__,
+ NULL); /* should never happen! */
}
-END:
- if (0 != ioff)
+AGAIN:
+ if (ioff > 0)
{
memmove (buf,
&buf[ioff],
pp->buffer_pos - ioff);
pp->buffer_pos -= ioff;
+ ioff = 0;
+ state_changed = 1;
}
+ }
+END:
+ if (0 != ioff)
+ {
+ memmove (buf,
+ &buf[ioff],
+ pp->buffer_pos - ioff);
+ pp->buffer_pos -= ioff;
+ }
if (poff < post_data_len)
- {
- pp->state = PP_Error;
- return MHD_NO; /* serious error */
- }
+ {
+ pp->state = PP_Error;
+ return MHD_NO; /* serious error */
+ }
return MHD_YES;
}
-/**
- * Parse and process POST data. Call this function when POST data is
- * available (usually during an #MHD_AccessHandlerCallback) with the
- * "upload_data" and "upload_data_size". Whenever possible, this will
- * then cause calls to the #MHD_PostDataIterator.
- *
- * @param pp the post processor
- * @param post_data @a post_data_len bytes of POST data
- * @param post_data_len length of @a post_data
- * @return #MHD_YES on success, #MHD_NO on error
- * (out-of-memory, iterator aborted, parse error)
- * @ingroup request
- */
-int
+enum MHD_Result
MHD_post_process (struct MHD_PostProcessor *pp,
const char *post_data,
size_t post_data_len)
@@ -1221,13 +1394,15 @@
return MHD_NO;
if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
pp->encoding,
- MHD_STATICSTR_LEN_(MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
return post_process_urlencoded (pp,
post_data,
post_data_len);
if (MHD_str_equal_caseless_n_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA,
pp->encoding,
- MHD_STATICSTR_LEN_ (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
+ MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
return post_process_multipart (pp,
post_data,
post_data_len);
@@ -1236,20 +1411,10 @@
}
-/**
- * Release PostProcessor resources.
- *
- * @param pp post processor context to destroy
- * @return #MHD_YES if processing completed nicely,
- * #MHD_NO if there were spurious characters / formatting
- * problems; it is common to ignore the return
- * value of this function
- * @ingroup request
- */
-int
+enum MHD_Result
MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
{
- int ret;
+ enum MHD_Result ret;
if (NULL == pp)
return MHD_YES;
@@ -1267,7 +1432,7 @@
at any stage */
if ( (pp->xbuf_pos > 0) ||
( (pp->state != PP_Done) &&
- (pp->state != PP_ExpectNewLine) ) )
+ (pp->state != PP_Init) ) )
ret = MHD_NO;
else
ret = MHD_YES;
@@ -1279,4 +1444,5 @@
return ret;
}
+
/* end of postprocessor.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/reason_phrase.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007, 2011, 2017 Christian Grothoff, Karlson2k (Evgeny Grin)
+ Copyright (C) 2007, 2011, 2017, 2019 Christian Grothoff, Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
#include "microhttpd.h"
#ifndef NULL
-#define NULL ((void*)0)
+#define NULL ((void*) 0)
#endif
static const char *const invalid_hundred[] = {
@@ -36,121 +36,122 @@
};
static const char *const one_hundred[] = {
- "Continue",
- "Switching Protocols",
- "Processing"
+ /* 100 */ "Continue", /* RFC7231, Section 6.2.1 */
+ /* 101 */ "Switching Protocols", /* RFC7231, Section 6.2.2 */
+ /* 102 */ "Processing", /* RFC2518 */
+ /* 103 */ "Early Hints" /* RFC8297 */
};
static const char *const two_hundred[] = {
- "OK",
- "Created",
- "Accepted",
- "Non-Authoritative Information",
- "No Content",
- "Reset Content",
- "Partial Content",
- "Multi-Status",
- "Already Reported",
- "Unknown",
- "Unknown", /* 210 */
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown", /* 215 */
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown", /* 220 */
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown", /* 225 */
- "IM Used"
+ /* 200 */ "OK", /* RFC7231, Section 6.3.1 */
+ /* 201 */ "Created", /* RFC7231, Section 6.3.2 */
+ /* 202 */ "Accepted", /* RFC7231, Section 6.3.3 */
+ /* 203 */ "Non-Authoritative Information", /* RFC7231, Section 6.3.4 */
+ /* 204 */ "No Content", /* RFC7231, Section 6.3.5 */
+ /* 205 */ "Reset Content", /* RFC7231, Section 6.3.6 */
+ /* 206 */ "Partial Content", /* RFC7233, Section 4.1 */
+ /* 207 */ "Multi-Status", /* RFC4918 */
+ /* 208 */ "Already Reported", /* RFC5842 */
+ /* 209 */ "Unknown", /* Not used */
+ /* 210 */ "Unknown", /* Not used */
+ /* 211 */ "Unknown", /* Not used */
+ /* 212 */ "Unknown", /* Not used */
+ /* 213 */ "Unknown", /* Not used */
+ /* 214 */ "Unknown", /* Not used */
+ /* 215 */ "Unknown", /* Not used */
+ /* 216 */ "Unknown", /* Not used */
+ /* 217 */ "Unknown", /* Not used */
+ /* 218 */ "Unknown", /* Not used */
+ /* 219 */ "Unknown", /* Not used */
+ /* 220 */ "Unknown", /* Not used */
+ /* 221 */ "Unknown", /* Not used */
+ /* 222 */ "Unknown", /* Not used */
+ /* 223 */ "Unknown", /* Not used */
+ /* 224 */ "Unknown", /* Not used */
+ /* 225 */ "Unknown", /* Not used */
+ /* 226 */ "IM Used" /* RFC3229 */
};
static const char *const three_hundred[] = {
- "Multiple Choices",
- "Moved Permanently",
- "Found",
- "See Other",
- "Not Modified",
- "Use Proxy",
- "Switch Proxy",
- "Temporary Redirect",
- "Permanent Redirect"
+ /* 300 */ "Multiple Choices", /* RFC7231, Section 6.4.1 */
+ /* 301 */ "Moved Permanently", /* RFC7231, Section 6.4.2 */
+ /* 302 */ "Found", /* RFC7231, Section 6.4.3 */
+ /* 303 */ "See Other", /* RFC7231, Section 6.4.4 */
+ /* 304 */ "Not Modified", /* RFC7232, Section 4.1 */
+ /* 305 */ "Use Proxy", /* RFC7231, Section 6.4.5 */
+ /* 306 */ "Switch Proxy", /* Not used! RFC7231, Section 6.4.6 */
+ /* 307 */ "Temporary Redirect", /* RFC7231, Section 6.4.7 */
+ /* 308 */ "Permanent Redirect" /* RFC7538 */
};
static const char *const four_hundred[] = {
- "Bad Request",
- "Unauthorized",
- "Payment Required",
- "Forbidden",
- "Not Found",
- "Method Not Allowed",
- "Not Acceptable",
- "Proxy Authentication Required",
- "Request Timeout",
- "Conflict",
- "Gone",
- "Length Required",
- "Precondition Failed",
- "Payload Too Large",
- "URI Too Long",
- "Unsupported Media Type",
- "Range Not Satisfiable",
- "Expectation Failed",
- "Unknown",
- "Unknown",
- "Unknown", /* 420 */
- "Misdirected Request",
- "Unprocessable Entity",
- "Locked",
- "Failed Dependency",
- "Unordered Collection",
- "Upgrade Required",
- "Unknown",
- "Precondition Required",
- "Too Many Requests",
- "Unknown", /* 430 */
- "Request Header Fields Too Large",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown", /* 435 */
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown", /* 440 */
- "Unknown",
- "Unknown",
- "Unknown",
- "No Response",
- "Unknown", /* 445 */
- "Unknown",
- "Unknown",
- "Unknown",
- "Retry With",
- "Blocked by Windows Parental Controls", /* 450 */
- "Unavailable For Legal Reasons"
+ /* 400 */ "Bad Request", /* RFC7231, Section 6.5.1 */
+ /* 401 */ "Unauthorized", /* RFC7235, Section 3.1 */
+ /* 402 */ "Payment Required", /* RFC7231, Section 6.5.2 */
+ /* 403 */ "Forbidden", /* RFC7231, Section 6.5.3 */
+ /* 404 */ "Not Found", /* RFC7231, Section 6.5.4 */
+ /* 405 */ "Method Not Allowed", /* RFC7231, Section 6.5.5 */
+ /* 406 */ "Not Acceptable", /* RFC7231, Section 6.5.6 */
+ /* 407 */ "Proxy Authentication Required", /* RFC7235, Section 3.2 */
+ /* 408 */ "Request Timeout", /* RFC7231, Section 6.5.7 */
+ /* 409 */ "Conflict", /* RFC7231, Section 6.5.8 */
+ /* 410 */ "Gone", /* RFC7231, Section 6.5.9 */
+ /* 411 */ "Length Required", /* RFC7231, Section 6.5.10 */
+ /* 412 */ "Precondition Failed", /* RFC7232, Section 4.2; RFC8144, Section 3.2 */
+ /* 413 */ "Payload Too Large", /* RFC7231, Section 6.5.11 */
+ /* 414 */ "URI Too Long", /* RFC7231, Section 6.5.12 */
+ /* 415 */ "Unsupported Media Type", /* RFC7231, Section 6.5.13; RFC7694, Section 3 */
+ /* 416 */ "Range Not Satisfiable", /* RFC7233, Section 4.4 */
+ /* 417 */ "Expectation Failed", /* RFC7231, Section 6.5.14 */
+ /* 418 */ "Unknown", /* Not used */
+ /* 419 */ "Unknown", /* Not used */
+ /* 420 */ "Unknown", /* Not used */
+ /* 421 */ "Misdirected Request", /* RFC7540, Section 9.1.2 */
+ /* 422 */ "Unprocessable Entity", /* RFC4918 */
+ /* 423 */ "Locked", /* RFC4918 */
+ /* 424 */ "Failed Dependency", /* RFC4918 */
+ /* 425 */ "Too Early", /* RFC8470 */
+ /* 426 */ "Upgrade Required", /* RFC7231, Section 6.5.15 */
+ /* 427 */ "Unknown", /* Not used */
+ /* 428 */ "Precondition Required", /* RFC6585 */
+ /* 429 */ "Too Many Requests", /* RFC6585 */
+ /* 430 */ "Unknown", /* Not used */
+ /* 431 */ "Request Header Fields Too Large", /* RFC6585 */
+ /* 432 */ "Unknown", /* Not used */
+ /* 433 */ "Unknown", /* Not used */
+ /* 434 */ "Unknown", /* Not used */
+ /* 435 */ "Unknown", /* Not used */
+ /* 436 */ "Unknown", /* Not used */
+ /* 437 */ "Unknown", /* Not used */
+ /* 438 */ "Unknown", /* Not used */
+ /* 439 */ "Unknown", /* Not used */
+ /* 440 */ "Unknown", /* Not used */
+ /* 441 */ "Unknown", /* Not used */
+ /* 442 */ "Unknown", /* Not used */
+ /* 443 */ "Unknown", /* Not used */
+ /* 444 */ "Unknown", /* Not used */
+ /* 445 */ "Unknown", /* Not used */
+ /* 446 */ "Unknown", /* Not used */
+ /* 447 */ "Unknown", /* Not used */
+ /* 448 */ "Unknown", /* Not used */
+ /* 449 */ "Reply With", /* MS IIS extension */
+ /* 450 */ "Blocked by Windows Parental Controls", /* MS extension */
+ /* 451 */ "Unavailable For Legal Reasons" /* RFC7725 */
};
static const char *const five_hundred[] = {
- "Internal Server Error",
- "Not Implemented",
- "Bad Gateway",
- "Service Unavailable",
- "Gateway Timeout",
- "HTTP Version Not Supported",
- "Variant Also Negotiates",
- "Insufficient Storage",
- "Loop Detected",
- "Bandwidth Limit Exceeded",
- "Not Extended",
- "Network Authentication Required"
+ /* 500 */ "Internal Server Error", /* RFC7231, Section 6.6.1 */
+ /* 501 */ "Not Implemented", /* RFC7231, Section 6.6.2 */
+ /* 502 */ "Bad Gateway", /* RFC7231, Section 6.6.3 */
+ /* 503 */ "Service Unavailable", /* RFC7231, Section 6.6.4 */
+ /* 504 */ "Gateway Timeout", /* RFC7231, Section 6.6.5 */
+ /* 505 */ "HTTP Version Not Supported", /* RFC7231, Section 6.6.6 */
+ /* 506 */ "Variant Also Negotiates", /* RFC2295 */
+ /* 507 */ "Insufficient Storage", /* RFC4918 */
+ /* 508 */ "Loop Detected", /* RFC5842 */
+ /* 509 */ "Bandwidth Limit Exceeded", /* Apache extension */
+ /* 510 */ "Not Extended", /* RFC2774 */
+ /* 511 */ "Network Authentication Required" /* RFC6585 */
};
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/response.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007, 2009, 2010, 2016, 2017 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2021 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -30,9 +30,9 @@
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif /* HAVE_SYS_IOCTL_H */
-#ifdef _WIN32
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#include <windows.h>
-#endif /* _WIN32 */
+#endif /* _WIN32 && !__CYGWIN__ */
#include "internal.h"
#include "response.h"
@@ -42,21 +42,35 @@
#include "mhd_str.h"
#include "connection.h"
#include "memorypool.h"
+#include "mhd_send.h"
#include "mhd_compat.h"
-#if defined(_WIN32) && defined(MHD_W32_MUTEX_)
+#if defined(MHD_W32_MUTEX_)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif /* !WIN32_LEAN_AND_MEAN */
#include <windows.h>
-#endif /* _WIN32 && MHD_W32_MUTEX_ */
+#endif /* MHD_W32_MUTEX_ */
#if defined(_WIN32)
#include <io.h> /* for lseek(), read() */
#endif /* _WIN32 */
/**
+ * Size of single file read operation for
+ * file-backed responses.
+ */
+#ifndef MHD_FILE_READ_BLOCK_SIZE
+#ifdef _WIN32
+#define MHD_FILE_READ_BLOCK_SIZE 16384 /* 16k */
+#else /* _WIN32 */
+#define MHD_FILE_READ_BLOCK_SIZE 4096 /* 4k */
+#endif /* _WIN32 */
+#endif /* !MHD_FD_BLOCK_SIZE */
+
+
+/**
* Add a header or footer line to the response.
*
* @param response response to add a header to
@@ -65,11 +79,11 @@
* @param content value to add
* @return #MHD_NO on error (i.e. invalid header or content format).
*/
-static int
+static enum MHD_Result
add_response_entry (struct MHD_Response *response,
- enum MHD_ValueKind kind,
- const char *header,
- const char *content)
+ enum MHD_ValueKind kind,
+ const char *header,
+ const char *content)
{
struct MHD_HTTP_Header *hdr;
@@ -88,16 +102,18 @@
if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
return MHD_NO;
if (NULL == (hdr->header = strdup (header)))
- {
- free (hdr);
- return MHD_NO;
- }
+ {
+ free (hdr);
+ return MHD_NO;
+ }
+ hdr->header_size = strlen (header);
if (NULL == (hdr->value = strdup (content)))
- {
- free (hdr->header);
- free (hdr);
- return MHD_NO;
- }
+ {
+ free (hdr->header);
+ free (hdr);
+ return MHD_NO;
+ }
+ hdr->value_size = strlen (content);
hdr->kind = kind;
hdr->next = response->first_header;
response->first_header = hdr;
@@ -114,15 +130,38 @@
* @return #MHD_NO on error (i.e. invalid header or content format).
* @ingroup response
*/
-int
+enum MHD_Result
MHD_add_response_header (struct MHD_Response *response,
const char *header,
const char *content)
{
+ if ( (MHD_str_equal_caseless_ (header,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING)) &&
+ (! MHD_str_equal_caseless_ (content,
+ "identity")) &&
+ (! MHD_str_equal_caseless_ (content,
+ "chunked")) )
+ {
+ /* Setting transfer encodings other than "identity" or
+ "chunked" is not allowed. Note that MHD will set the
+ correct transfer encoding if required automatically. */
+ /* NOTE: for compressed bodies, use the "Content-encoding" header */
+ return MHD_NO;
+ }
+ if ( (0 == (MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
+ & response->flags)) &&
+ (MHD_str_equal_caseless_ (header,
+ MHD_HTTP_HEADER_CONTENT_LENGTH)) )
+ {
+ /* MHD will set Content-length if allowed and possible,
+ reject attempt by application */
+ return MHD_NO;
+ }
+
return add_response_entry (response,
- MHD_HEADER_KIND,
- header,
- content);
+ MHD_HEADER_KIND,
+ header,
+ content);
}
@@ -135,15 +174,15 @@
* @return #MHD_NO on error (i.e. invalid footer or content format).
* @ingroup response
*/
-int
+enum MHD_Result
MHD_add_response_footer (struct MHD_Response *response,
const char *footer,
const char *content)
{
return add_response_entry (response,
- MHD_FOOTER_KIND,
- footer,
- content);
+ MHD_FOOTER_KIND,
+ footer,
+ content);
}
@@ -156,38 +195,46 @@
* @return #MHD_NO on error (no such header known)
* @ingroup response
*/
-int
+enum MHD_Result
MHD_del_response_header (struct MHD_Response *response,
const char *header,
- const char *content)
+ const char *content)
{
struct MHD_HTTP_Header *pos;
struct MHD_HTTP_Header *prev;
+ size_t header_len;
+ size_t content_len;
if ( (NULL == header) ||
- (NULL == content) )
+ (NULL == content) )
return MHD_NO;
+ header_len = strlen (header);
+ content_len = strlen (content);
prev = NULL;
pos = response->first_header;
- while (pos != NULL)
+ while (NULL != pos)
+ {
+ if ((header_len == pos->header_size) &&
+ (content_len == pos->value_size) &&
+ (0 == memcmp (header,
+ pos->header,
+ header_len)) &&
+ (0 == memcmp (content,
+ pos->value,
+ content_len)))
{
- if ((0 == strcmp (header,
- pos->header)) &&
- (0 == strcmp (content,
- pos->value)))
- {
- free (pos->header);
- free (pos->value);
- if (NULL == prev)
- response->first_header = pos->next;
- else
- prev->next = pos->next;
- free (pos);
- return MHD_YES;
- }
- prev = pos;
- pos = pos->next;
+ free (pos->header);
+ free (pos->value);
+ if (NULL == prev)
+ response->first_header = pos->next;
+ else
+ prev->next = pos->next;
+ free (pos);
+ return MHD_YES;
}
+ prev = pos;
+ pos = pos->next;
+ }
return MHD_NO;
}
@@ -207,19 +254,21 @@
MHD_KeyValueIterator iterator,
void *iterator_cls)
{
- struct MHD_HTTP_Header *pos;
int numHeaders = 0;
+ struct MHD_HTTP_Header *pos;
- for (pos = response->first_header; NULL != pos; pos = pos->next)
- {
- numHeaders++;
- if ((NULL != iterator) &&
- (MHD_YES != iterator (iterator_cls,
- pos->kind,
- pos->header,
- pos->value)))
- break;
- }
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ numHeaders++;
+ if ((NULL != iterator) &&
+ (MHD_NO == iterator (iterator_cls,
+ pos->kind,
+ pos->header,
+ pos->value)))
+ break;
+ }
return numHeaders;
}
@@ -234,29 +283,39 @@
*/
const char *
MHD_get_response_header (struct MHD_Response *response,
- const char *key)
+ const char *key)
{
struct MHD_HTTP_Header *pos;
+ size_t key_size;
if (NULL == key)
return NULL;
- for (pos = response->first_header; NULL != pos; pos = pos->next)
- {
- if ( MHD_str_equal_caseless_ (pos->header, key) )
- return pos->value;
- }
+
+ key_size = strlen (key);
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if ((pos->header_size == key_size) &&
+ (MHD_str_equal_caseless_bin_n_ (pos->header, key, pos->header_size)))
+ return pos->value;
+ }
return NULL;
}
+
/**
* Check whether response header contains particular token.
*
* Token could be surrounded by spaces and tabs and delimited by comma.
* Case-insensitive match used for header names and tokens.
+ *
* @param response the response to query
* @param key header name
+ * @param key_len the length of @a key, not including optional
+ * terminating null-character.
* @param token the token to find
- * @param token_len the length of token, not including optional
+ * @param token_len the length of @a token, not including optional
* terminating null-character.
* @return true if token is found in specified header,
* false otherwise
@@ -264,21 +323,35 @@
bool
MHD_check_response_header_token_ci (const struct MHD_Response *response,
const char *key,
+ size_t key_len,
const char *token,
size_t token_len)
{
struct MHD_HTTP_Header *pos;
- if (NULL == key || 0 == key[0] || NULL == token || 0 == token[0])
+ if ( (NULL == key) ||
+ ('\0' == key[0]) ||
+ (NULL == token) ||
+ ('\0' == token[0]) )
return false;
- for (pos = response->first_header; NULL != pos; pos = pos->next)
- {
- if ( (pos->kind == MHD_HEADER_KIND) &&
- MHD_str_equal_caseless_ (pos->header, key) &&
- MHD_str_has_token_caseless_ (pos->value, token, token_len) )
- return true;
- }
+ /* Token must not contain binary zero! */
+ mhd_assert (strlen (token) == token_len);
+
+ for (pos = response->first_header;
+ NULL != pos;
+ pos = pos->next)
+ {
+ if ( (pos->kind == MHD_HEADER_KIND) &&
+ (key_len == pos->header_size) &&
+ MHD_str_equal_caseless_bin_n_ (pos->header,
+ key,
+ key_len) &&
+ MHD_str_has_token_caseless_ (pos->value,
+ token,
+ token_len) )
+ return true;
+ }
return false;
}
@@ -310,16 +383,19 @@
if ((NULL == crc) || (0 == block_size))
return NULL;
- if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response) + block_size)))
+ if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)
+ + block_size)))
return NULL;
response->fd = -1;
response->data = (void *) &response[1];
response->data_buffer_size = block_size;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if (! MHD_mutex_init_ (&response->mutex))
- {
- free (response);
- return NULL;
- }
+ {
+ free (response);
+ return NULL;
+ }
+#endif
response->crc = crc;
response->crfc = crfc;
response->crc_cls = crc_cls;
@@ -337,13 +413,13 @@
* @param ... #MHD_RO_END terminated list of options
* @return #MHD_YES on success, #MHD_NO on error
*/
-int
+enum MHD_Result
MHD_set_response_options (struct MHD_Response *response,
enum MHD_ResponseFlags flags,
...)
{
va_list ap;
- int ret;
+ enum MHD_Result ret;
enum MHD_ResponseOptions ro;
ret = MHD_YES;
@@ -380,28 +456,28 @@
size_t max)
{
struct MHD_Response *response = cls;
-#ifndef _WIN32
+#if ! defined(_WIN32) || defined(__CYGWIN__)
ssize_t n;
-#else /* _WIN32 */
+#else /* _WIN32 && !__CYGWIN__ */
const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
-#endif /* _WIN32 */
- const int64_t offset64 = (int64_t)(pos + response->fd_off);
+#endif /* _WIN32 && !__CYGWIN__ */
+ const int64_t offset64 = (int64_t) (pos + response->fd_off);
if (offset64 < 0)
return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
-#ifndef _WIN32
+#if ! defined(_WIN32) || defined(__CYGWIN__)
if (max > SSIZE_MAX)
max = SSIZE_MAX; /* Clamp to maximum return value. */
#if defined(HAVE_PREAD64)
- n = pread64(response->fd, buf, max, offset64);
+ n = pread64 (response->fd, buf, max, offset64);
#elif defined(HAVE_PREAD)
if ( (sizeof(off_t) < sizeof (uint64_t)) &&
- (offset64 > (uint64_t)INT32_MAX) )
+ (offset64 > (uint64_t) INT32_MAX) )
return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
- n = pread(response->fd, buf, max, (off_t) offset64);
+ n = pread (response->fd, buf, max, (off_t) offset64);
#else /* ! HAVE_PREAD */
#if defined(HAVE_LSEEK64)
if (lseek64 (response->fd,
@@ -410,7 +486,7 @@
return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
#else /* ! HAVE_LSEEK64 */
if ( (sizeof(off_t) < sizeof (uint64_t)) &&
- (offset64 > (uint64_t)INT32_MAX) )
+ (offset64 > (uint64_t) INT32_MAX) )
return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
if (lseek (response->fd,
@@ -428,26 +504,65 @@
if (n < 0)
return MHD_CONTENT_READER_END_WITH_ERROR;
return n;
-#else /* _WIN32 */
+#else /* _WIN32 && !__CYGWIN__ */
if (INVALID_HANDLE_VALUE == fh)
return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
else
- {
- OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
- ULARGE_INTEGER pos_uli;
- DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
- DWORD resRead;
-
- pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
- f_ol.Offset = pos_uli.LowPart;
- f_ol.OffsetHigh = pos_uli.HighPart;
- if (! ReadFile(fh, (void*)buf, toRead, &resRead, &f_ol))
- return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
- if (0 == resRead)
- return MHD_CONTENT_READER_END_OF_STREAM;
- return (ssize_t) resRead;
- }
+ {
+ OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
+ ULARGE_INTEGER pos_uli;
+ DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
+ DWORD resRead;
+
+ pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
+ f_ol.Offset = pos_uli.LowPart;
+ f_ol.OffsetHigh = pos_uli.HighPart;
+ if (! ReadFile (fh, (void*) buf, toRead, &resRead, &f_ol))
+ return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
+ if (0 == resRead)
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ return (ssize_t) resRead;
+ }
+#endif /* _WIN32 && !__CYGWIN__ */
+}
+
+
+/**
+ * Given a pipe descriptor, read data from the pipe
+ * to generate the response.
+ *
+ * @param cls pointer to the response
+ * @param pos offset in the pipe to access (ignored)
+ * @param buf where to write the data
+ * @param max number of bytes to write at most
+ * @return number of bytes written
+ */
+static ssize_t
+pipe_reader (void *cls,
+ uint64_t pos,
+ char *buf,
+ size_t max)
+{
+ struct MHD_Response *response = cls;
+ ssize_t n;
+
+ (void) pos;
+#ifndef _WIN32
+ if (SSIZE_MAX < max)
+ max = SSIZE_MAX;
+#else /* _WIN32 */
+ if (UINT_MAX < max)
+ max = UINT_MAX;
#endif /* _WIN32 */
+
+ n = read (response->fd,
+ buf,
+ (MHD_SCKT_SEND_SIZE_) max);
+ if (0 == n)
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ if (n < 0)
+ return MHD_CONTENT_READER_END_WITH_ERROR;
+ return n;
}
@@ -466,6 +581,7 @@
response->fd = -1;
}
+
#undef MHD_create_response_from_fd_at_offset
/**
@@ -486,8 +602,8 @@
*/
struct MHD_Response *
MHD_create_response_from_fd_at_offset (size_t size,
- int fd,
- off_t offset)
+ int fd,
+ off_t offset)
{
return MHD_create_response_from_fd_at_offset64 (size,
fd,
@@ -518,26 +634,27 @@
{
struct MHD_Response *response;
-#if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64)
+#if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
if ( (sizeof(uint64_t) > sizeof(off_t)) &&
- ( (size > (uint64_t)INT32_MAX) ||
- (offset > (uint64_t)INT32_MAX) ||
- ((size + offset) >= (uint64_t)INT32_MAX) ) )
+ ( (size > (uint64_t) INT32_MAX) ||
+ (offset > (uint64_t) INT32_MAX) ||
+ ((size + offset) >= (uint64_t) INT32_MAX) ) )
return NULL;
#endif
- if ( ((int64_t)size < 0) ||
- ((int64_t)offset < 0) ||
- ((int64_t)(size + offset) < 0) )
+ if ( ((int64_t) size < 0) ||
+ ((int64_t) offset < 0) ||
+ ((int64_t) (size + offset) < 0) )
return NULL;
response = MHD_create_response_from_callback (size,
- 4 * 1024,
- &file_reader,
- NULL,
- &free_callback);
+ MHD_FILE_READ_BLOCK_SIZE,
+ &file_reader,
+ NULL,
+ &free_callback);
if (NULL == response)
return NULL;
response->fd = fd;
+ response->is_pipe = false;
response->fd_off = offset;
response->crc_cls = response;
return response;
@@ -546,6 +663,35 @@
/**
* Create a response object. The response object can be extended with
+ * header information and then be used ONLY ONCE.
+ *
+ * @param fd file descriptor referring to a read-end of a pipe with the
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_pipe (int fd)
+{
+ struct MHD_Response *response;
+
+ response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
+ MHD_FILE_READ_BLOCK_SIZE,
+ &pipe_reader,
+ NULL,
+ &free_callback);
+ if (NULL == response)
+ return NULL;
+ response->fd = fd;
+ response->is_pipe = true;
+ response->crc_cls = response;
+ return response;
+}
+
+
+/**
+ * Create a response object. The response object can be extended with
* header information and then be used any number of times.
*
* @param size size of the data portion of the response
@@ -555,7 +701,7 @@
*/
struct MHD_Response *
MHD_create_response_from_fd (size_t size,
- int fd)
+ int fd)
{
return MHD_create_response_from_fd_at_offset64 (size,
fd,
@@ -614,32 +760,38 @@
if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
return NULL;
response->fd = -1;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if (! MHD_mutex_init_ (&response->mutex))
+ {
+ free (response);
+ return NULL;
+ }
+#endif
+ if ((must_copy) && (size > 0))
+ {
+ if (NULL == (tmp = malloc (size)))
{
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_destroy_chk_ (&response->mutex);
+#endif
free (response);
return NULL;
}
- if ((must_copy) && (size > 0))
- {
- if (NULL == (tmp = malloc (size)))
- {
- MHD_mutex_destroy_chk_ (&response->mutex);
- free (response);
- return NULL;
- }
- memcpy (tmp, data, size);
- must_free = MHD_YES;
- data = tmp;
- }
+ memcpy (tmp, data, size);
+ must_free = MHD_YES;
+ data = tmp;
+ }
if (must_free)
- {
- response->crfc = &free;
- response->crc_cls = data;
- }
+ {
+ response->crfc = &free;
+ response->crc_cls = data;
+ }
response->reference_count = 1;
response->total_size = size;
response->data = data;
response->data_size = size;
+ if (must_copy)
+ response->data_buffer_size = size;
return response;
}
@@ -656,13 +808,182 @@
*/
struct MHD_Response *
MHD_create_response_from_buffer (size_t size,
- void *buffer,
- enum MHD_ResponseMemoryMode mode)
+ void *buffer,
+ enum MHD_ResponseMemoryMode mode)
{
return MHD_create_response_from_data (size,
- buffer,
- mode == MHD_RESPMEM_MUST_FREE,
- mode == MHD_RESPMEM_MUST_COPY);
+ buffer,
+ mode == MHD_RESPMEM_MUST_FREE,
+ mode == MHD_RESPMEM_MUST_COPY);
+}
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
+ * @param buffer size bytes containing the response's data portion
+ * @param crfc function to call to free the @a buffer
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ * @ingroup response
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_buffer_with_free_callback (size_t size,
+ void *buffer,
+ MHD_ContentReaderFreeCallback
+ crfc)
+{
+ struct MHD_Response *r;
+
+ r = MHD_create_response_from_data (size,
+ buffer,
+ MHD_YES,
+ MHD_NO);
+ if (NULL == r)
+ return r;
+ r->crfc = crfc;
+ return r;
+}
+
+
+/**
+ * Create a response object from an array of memory buffers.
+ * The response object can be extended with header information and then be used
+ * any number of times.
+ *
+ * @param iov the array for response data buffers, an internal copy of this
+ * will be made
+ * @param iovcnt the number of elements in @a iov
+ * @param free_cb the callback to clean up any data associated with @a iov when
+ * the response is destroyed.
+ * @param cls the argument passed to @a free_cb
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+_MHD_EXTERN struct MHD_Response *
+MHD_create_response_from_iovec (const struct MHD_IoVec *iov,
+ unsigned int iovcnt,
+ MHD_ContentReaderFreeCallback free_cb,
+ void *cls)
+{
+ struct MHD_Response *response;
+ unsigned int i;
+ int i_cp = 0; /**< Index in the copy of iov */
+ uint64_t total_size = 0;
+ const void *last_valid_buffer = NULL;
+
+ if ((NULL == iov) && (0 < iovcnt))
+ return NULL;
+
+ response = MHD_calloc_ (1, sizeof (struct MHD_Response));
+ if (NULL == response)
+ return NULL;
+ if (! MHD_mutex_init_ (&response->mutex))
+ {
+ free (response);
+ return NULL;
+ }
+ /* Calculate final size, number of valid elements, and check 'iov' */
+ for (i = 0; i < iovcnt; ++i)
+ {
+ if (0 == iov[i].iov_len)
+ continue; /* skip zero-sized elements */
+ if (NULL == iov[i].iov_base)
+ {
+ i_cp = -1; /* error */
+ break;
+ }
+ if ( (total_size > (total_size + iov[i].iov_len)) ||
+ (INT_MAX == i_cp) ||
+ (SSIZE_MAX < (total_size + iov[i].iov_len)) )
+ {
+ i_cp = -1; /* overflow */
+ break;
+ }
+ last_valid_buffer = iov[i].iov_base;
+ total_size += iov[i].iov_len;
+#if defined(MHD_POSIX_SOCKETS) || ! defined(_WIN64)
+ i_cp++;
+#else /* ! MHD_POSIX_SOCKETS && _WIN64 */
+ {
+ int64_t i_add;
+
+ i_add = iov[i].iov_len / ULONG_MAX;
+ if (0 != iov[i].iov_len % ULONG_MAX)
+ i_add++;
+ if (INT_MAX < (i_add + i_cp))
+ {
+ i_cp = -1; /* overflow */
+ break;
+ }
+ i_cp += (int) i_add;
+ }
+#endif /* ! MHD_POSIX_SOCKETS && _WIN64 */
+ }
+ if (-1 == i_cp)
+ {
+ /* Some error condition */
+ MHD_mutex_destroy_chk_ (&response->mutex);
+ free (response);
+ return NULL;
+ }
+ response->fd = -1;
+ response->reference_count = 1;
+ response->total_size = total_size;
+ response->crc_cls = cls;
+ response->crfc = free_cb;
+ if (0 == i_cp)
+ {
+ mhd_assert (0 == total_size);
+ return response;
+ }
+ if (1 == i_cp)
+ {
+ mhd_assert (NULL != last_valid_buffer);
+ response->data = (void *) last_valid_buffer;
+ response->data_size = (size_t) total_size;
+ return response;
+ }
+ mhd_assert (1 < i_cp);
+ {
+ MHD_iovec_ *iov_copy;
+ int num_copy_elements = i_cp;
+
+ iov_copy = MHD_calloc_ (num_copy_elements,
+ sizeof(MHD_iovec_));
+ if (NULL == iov_copy)
+ {
+ MHD_mutex_destroy_chk_ (&response->mutex);
+ free (response);
+ return NULL;
+ }
+ i_cp = 0;
+ for (i = 0; i < iovcnt; ++i)
+ {
+ size_t element_size = iov[i].iov_len;
+ const uint8_t *buf = (const uint8_t *) iov[i].iov_base;
+
+ if (0 == element_size)
+ continue; /* skip zero-sized elements */
+#if defined(MHD_WINSOCK_SOCKETS) && defined(_WIN64)
+ while (MHD_IOV_ELMN_MAX_SIZE < element_size)
+ {
+ iov_copy[i_cp].iov_base = (char *) buf;
+ iov_copy[i_cp].iov_len = ULONG_MAX;
+ buf += ULONG_MAX;
+ element_size -= ULONG_MAX;
+ i_cp++;
+ }
+#endif /* MHD_WINSOCK_SOCKETS && _WIN64 */
+ iov_copy[i_cp].iov_base = (void *) buf;
+ iov_copy[i_cp].iov_len = (MHD_iov_size_) element_size;
+ i_cp++;
+ }
+ mhd_assert (num_copy_elements == i_cp);
+ response->data_iov = iov_copy;
+ response->data_iovcnt = i_cp;
+ return response;
+ }
}
@@ -679,7 +1000,7 @@
* @param ... arguments to the action (depends on the action)
* @return #MHD_NO on error, #MHD_YES on success
*/
-_MHD_EXTERN int
+_MHD_EXTERN enum MHD_Result
MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
enum MHD_UpgradeAction action,
...)
@@ -707,20 +1028,28 @@
/* transition to special 'closed' state for start of cleanup */
#ifdef HTTPS_SUPPORT
if (0 != (daemon->options & MHD_USE_TLS) )
- {
- /* signal that app is done by shutdown() of 'app' socket */
- /* Application will not use anyway this socket after this command. */
- shutdown (urh->app.socket,
- SHUT_RDWR);
- }
+ {
+ /* signal that app is done by shutdown() of 'app' socket */
+ /* Application will not use anyway this socket after this command. */
+ shutdown (urh->app.socket,
+ SHUT_RDWR);
+ }
#endif /* HTTPS_SUPPORT */
- EXTRA_CHECK (MHD_CONNECTION_UPGRADE == connection->state);
+ mhd_assert (MHD_CONNECTION_UPGRADE == connection->state);
urh->was_closed = true;
/* As soon as connection will be marked with BOTH
* 'urh->was_closed' AND 'urh->clean_ready', it will
* be moved to cleanup list by MHD_resume_connection(). */
MHD_resume_connection (connection);
return MHD_YES;
+ case MHD_UPGRADE_ACTION_CORK_ON:
+ /* Unportable API. TODO: replace with portable action. */
+ return MHD_connection_set_cork_state_ (connection,
+ true) ? MHD_YES : MHD_NO;
+ case MHD_UPGRADE_ACTION_CORK_OFF:
+ /* Unportable API. TODO: replace with portable action. */
+ return MHD_connection_set_cork_state_ (connection,
+ false) ? MHD_YES : MHD_NO;
default:
/* we don't understand this one */
return MHD_NO;
@@ -741,7 +1070,7 @@
* @return #MHD_YES on success, #MHD_NO on failure (will cause
* connection to be closed)
*/
-int
+enum MHD_Result
MHD_response_execute_upgrade_ (struct MHD_Response *response,
struct MHD_Connection *connection)
{
@@ -749,19 +1078,25 @@
struct MHD_UpgradeResponseHandle *urh;
size_t rbo;
+#ifdef MHD_USE_THREADS
+ mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
+ MHD_thread_ID_match_current_ (connection->pid) );
+#endif /* MHD_USE_THREADS */
+
if (0 == (daemon->options & MHD_ALLOW_UPGRADE))
return MHD_NO;
if (NULL ==
MHD_get_response_header (response,
MHD_HTTP_HEADER_UPGRADE))
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
+ MHD_DLOG (daemon,
+ _ (
+ "Invalid response for upgrade: application failed to set the 'Upgrade' header!\n"));
#endif
- return MHD_NO;
- }
+ return MHD_NO;
+ }
urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle));
if (NULL == urh)
@@ -769,6 +1104,8 @@
urh->connection = connection;
rbo = connection->read_buffer_offset;
connection->read_buffer_offset = 0;
+ MHD_connection_set_nodelay_state_ (connection, false);
+ MHD_connection_set_cork_state_ (connection, false);
#ifdef HTTPS_SUPPORT
if (0 != (daemon->options & MHD_USE_TLS) )
{
@@ -776,77 +1113,77 @@
size_t avail;
char *buf;
MHD_socket sv[2];
-#if defined(MHD_socket_nosignal_) || !defined(MHD_socket_pair_nblk_)
+#if defined(MHD_socket_nosignal_) || ! defined(MHD_socket_pair_nblk_)
int res1;
int res2;
#endif /* MHD_socket_nosignal_ || !MHD_socket_pair_nblk_ */
#ifdef MHD_socket_pair_nblk_
if (! MHD_socket_pair_nblk_ (sv))
- {
- free (urh);
- return MHD_NO;
- }
+ {
+ free (urh);
+ return MHD_NO;
+ }
#else /* !MHD_socket_pair_nblk_ */
if (! MHD_socket_pair_ (sv))
- {
- free (urh);
- return MHD_NO;
- }
- res1 = MHD_socket_nonblocking_(sv[0]);
- res2 = MHD_socket_nonblocking_(sv[1]);
+ {
+ free (urh);
+ return MHD_NO;
+ }
+ res1 = MHD_socket_nonblocking_ (sv[0]);
+ res2 = MHD_socket_nonblocking_ (sv[1]);
if ( (! res1) || (! res2) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to make loopback sockets non-blocking.\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to make loopback sockets non-blocking.\n"));
#endif
- if (! res2)
- {
- /* Socketpair cannot be used. */
- MHD_socket_close_chk_ (sv[0]);
- MHD_socket_close_chk_ (sv[1]);
- free (urh);
- return MHD_NO;
- }
+ if (! res2)
+ {
+ /* Socketpair cannot be used. */
+ MHD_socket_close_chk_ (sv[0]);
+ MHD_socket_close_chk_ (sv[1]);
+ free (urh);
+ return MHD_NO;
}
+ }
#endif /* !MHD_socket_pair_nblk_ */
#ifdef MHD_socket_nosignal_
- res1 = MHD_socket_nosignal_(sv[0]);
- res2 = MHD_socket_nosignal_(sv[1]);
+ res1 = MHD_socket_nosignal_ (sv[0]);
+ res2 = MHD_socket_nosignal_ (sv[1]);
if ( (! res1) || (! res2) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
+ MHD_DLOG (daemon,
+ _ ("Failed to set SO_NOSIGPIPE on loopback sockets.\n"));
#endif
#ifndef MSG_NOSIGNAL
- if (!res2)
- {
- /* Socketpair cannot be used. */
- MHD_socket_close_chk_ (sv[0]);
- MHD_socket_close_chk_ (sv[1]);
- free (urh);
- return MHD_NO;
- }
-#endif /* ! MSG_NOSIGNAL */
+ if (! res2)
+ {
+ /* Socketpair cannot be used. */
+ MHD_socket_close_chk_ (sv[0]);
+ MHD_socket_close_chk_ (sv[1]);
+ free (urh);
+ return MHD_NO;
}
+#endif /* ! MSG_NOSIGNAL */
+ }
#endif /* MHD_socket_nosignal_ */
if ( (! MHD_SCKT_FD_FITS_FDSET_ (sv[1],
NULL)) &&
(0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
- {
+ {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
- (int) sv[1],
- (int) FD_SETSIZE);
+ MHD_DLOG (daemon,
+ _ ("Socketpair descriptor larger than FD_SETSIZE: %d > %d\n"),
+ (int) sv[1],
+ (int) FD_SETSIZE);
#endif
- MHD_socket_close_chk_ (sv[0]);
- MHD_socket_close_chk_ (sv[1]);
- free (urh);
- return MHD_NO;
- }
+ MHD_socket_close_chk_ (sv[0]);
+ MHD_socket_close_chk_ (sv[1]);
+ free (urh);
+ return MHD_NO;
+ }
urh->app.socket = sv[0];
urh->app.urh = urh;
urh->app.celi = MHD_EPOLL_STATE_UNREADY;
@@ -856,22 +1193,22 @@
pool = connection->pool;
avail = MHD_pool_get_free (pool);
if (avail < RESERVE_EBUF_SIZE)
- {
- /* connection's pool is totally at the limit,
- use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
- avail = RESERVE_EBUF_SIZE;
- buf = urh->e_buf;
- }
+ {
+ /* connection's pool is totally at the limit,
+ use our 'emergency' buffer of #RESERVE_EBUF_SIZE bytes. */
+ avail = RESERVE_EBUF_SIZE;
+ buf = urh->e_buf;
+ }
else
- {
- /* Normal case: grab all remaining memory from the
- connection's pool for the IO buffers; the connection
- certainly won't need it anymore as we've upgraded
- to another protocol. */
- buf = MHD_pool_allocate (pool,
- avail,
- MHD_NO);
- }
+ {
+ /* Normal case: grab all remaining memory from the
+ connection's pool for the IO buffers; the connection
+ certainly won't need it anymore as we've upgraded
+ to another protocol. */
+ buf = MHD_pool_allocate (pool,
+ avail,
+ false);
+ }
/* use half the buffer for inbound, half for outbound */
urh->in_buffer_size = avail / 2;
urh->out_buffer_size = avail - urh->in_buffer_size;
@@ -880,81 +1217,81 @@
#ifdef EPOLL_SUPPORT
/* Launch IO processing by the event loop */
if (0 != (daemon->options & MHD_USE_EPOLL))
+ {
+ /* We're running with epoll(), need to add the sockets
+ to the event set of the daemon's `epoll_upgrade_fd` */
+ struct epoll_event event;
+
+ mhd_assert (-1 != daemon->epoll_upgrade_fd);
+ /* First, add network socket */
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = &urh->app;
+ if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_ADD,
+ connection->socket_fd,
+ &event))
{
- /* We're running with epoll(), need to add the sockets
- to the event set of the daemon's `epoll_upgrade_fd` */
- struct epoll_event event;
-
- EXTRA_CHECK (-1 != daemon->epoll_upgrade_fd);
- /* First, add network socket */
- event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
- event.data.ptr = &urh->app;
- if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
- EPOLL_CTL_ADD,
- connection->socket_fd,
- &event))
- {
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- MHD_socket_close_chk_ (sv[0]);
- MHD_socket_close_chk_ (sv[1]);
- free (urh);
- return MHD_NO;
- }
-
- /* Second, add our end of the UNIX socketpair() */
- event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
- event.data.ptr = &urh->mhd;
+ MHD_socket_close_chk_ (sv[0]);
+ MHD_socket_close_chk_ (sv[1]);
+ free (urh);
+ return MHD_NO;
+ }
+
+ /* Second, add our end of the UNIX socketpair() */
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
+ event.data.ptr = &urh->mhd;
+ if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+ EPOLL_CTL_ADD,
+ urh->mhd.socket,
+ &event))
+ {
+ event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
+ event.data.ptr = &urh->app;
if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
- EPOLL_CTL_ADD,
- urh->mhd.socket,
+ EPOLL_CTL_DEL,
+ connection->socket_fd,
&event))
- {
- event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
- event.data.ptr = &urh->app;
- if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
- EPOLL_CTL_DEL,
- connection->socket_fd,
- &event))
- MHD_PANIC (_("Error cleaning up while handling epoll error"));
+ MHD_PANIC (_ ("Error cleaning up while handling epoll error.\n"));
#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _("Call to epoll_ctl failed: %s\n"),
- MHD_socket_last_strerr_ ());
+ MHD_DLOG (daemon,
+ _ ("Call to epoll_ctl failed: %s\n"),
+ MHD_socket_last_strerr_ ());
#endif
- MHD_socket_close_chk_ (sv[0]);
- MHD_socket_close_chk_ (sv[1]);
- free (urh);
- return MHD_NO;
- }
- EDLL_insert (daemon->eready_urh_head,
- daemon->eready_urh_tail,
- urh);
- urh->in_eready_list = true;
+ MHD_socket_close_chk_ (sv[0]);
+ MHD_socket_close_chk_ (sv[1]);
+ free (urh);
+ return MHD_NO;
}
+ EDLL_insert (daemon->eready_urh_head,
+ daemon->eready_urh_tail,
+ urh);
+ urh->in_eready_list = true;
+ }
#endif /* EPOLL_SUPPORT */
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
- {
- /* This takes care of further processing for most event loops:
- simply add to DLL for bi-direcitonal processing */
- DLL_insert (daemon->urh_head,
- daemon->urh_tail,
- urh);
- }
+ {
+ /* This takes care of further processing for most event loops:
+ simply add to DLL for bi-direcitonal processing */
+ DLL_insert (daemon->urh_head,
+ daemon->urh_tail,
+ urh);
+ }
/* In thread-per-connection mode, thread will switch to forwarding once
* connection.urh is not NULL and connection.state == MHD_CONNECTION_UPGRADE.
*/
}
else
- {
- urh->app.socket = MHD_INVALID_SOCKET;
- urh->mhd.socket = MHD_INVALID_SOCKET;
- /* Non-TLS connection do not hold any additional resources. */
- urh->clean_ready = true;
- }
+ {
+ urh->app.socket = MHD_INVALID_SOCKET;
+ urh->mhd.socket = MHD_INVALID_SOCKET;
+ /* Non-TLS connection do not hold any additional resources. */
+ urh->clean_ready = true;
+ }
#else /* ! HTTPS_SUPPORT */
urh->clean_ready = true;
#endif /* ! HTTPS_SUPPORT */
@@ -1012,7 +1349,7 @@
*/
_MHD_EXTERN struct MHD_Response *
MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
- void *upgrade_handler_cls)
+ void *upgrade_handler_cls)
{
struct MHD_Response *response;
@@ -1021,11 +1358,13 @@
response = MHD_calloc_ (1, sizeof (struct MHD_Response));
if (NULL == response)
return NULL;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
if (! MHD_mutex_init_ (&response->mutex))
- {
- free (response);
- return NULL;
- }
+ {
+ free (response);
+ return NULL;
+ }
+#endif
response->upgrade_handler = upgrade_handler;
response->upgrade_handler_cls = upgrade_handler_cls;
response->total_size = MHD_SIZE_UNKNOWN;
@@ -1034,12 +1373,14 @@
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONNECTION,
"Upgrade"))
- {
- MHD_destroy_response (response);
- return NULL;
- }
+ {
+ MHD_destroy_response (response);
+ return NULL;
+ }
return response;
}
+
+
#endif /* UPGRADE_SUPPORT */
@@ -1059,24 +1400,36 @@
if (NULL == response)
return;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&response->mutex);
+#endif
if (0 != --(response->reference_count))
- {
- MHD_mutex_unlock_chk_ (&response->mutex);
- return;
- }
+ {
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
+ return;
+ }
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&response->mutex);
MHD_mutex_destroy_chk_ (&response->mutex);
+#endif
if (NULL != response->crfc)
response->crfc (response->crc_cls);
+
+ if (NULL != response->data_iov)
+ {
+ free (response->data_iov);
+ }
+
while (NULL != response->first_header)
- {
- pos = response->first_header;
- response->first_header = pos->next;
- free (pos->header);
- free (pos->value);
- free (pos);
- }
+ {
+ pos = response->first_header;
+ response->first_header = pos->next;
+ free (pos->header);
+ free (pos->value);
+ free (pos);
+ }
free (response);
}
@@ -1089,9 +1442,13 @@
void
MHD_increment_response_rc (struct MHD_Response *response)
{
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_lock_chk_ (&response->mutex);
+#endif
(response->reference_count)++;
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
MHD_mutex_unlock_chk_ (&response->mutex);
+#endif
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/response.h
^
|
@@ -49,7 +49,7 @@
* @return #MHD_YES on success, #MHD_NO on failure (will cause
* connection to be closed)
*/
-int
+enum MHD_Result
MHD_response_execute_upgrade_ (struct MHD_Response *response,
struct MHD_Connection *connection);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/sha256.c
^
|
@@ -0,0 +1,373 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Karlson2k (Evgeny Grin)
+ Some ideas are based on Libgcrypt implementation.
+ Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
+
+ libmicrohttpd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/sha256.c
+ * @brief Calculation of SHA-256 digest as defined in FIPS PUB 180-4 (2015)
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+/* Some tricks are based on Libgcrypt implementation. */
+
+#include "sha256.h"
+
+#include <string.h>
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif /* HAVE_MEMORY_H */
+#include "mhd_bithelpers.h"
+#include "mhd_assert.h"
+
+/**
+ * Initialise structure for SHA256 calculation.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ */
+void
+MHD_SHA256_init (void *ctx_)
+{
+ struct sha256_ctx *const ctx = ctx_;
+ /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.3 */
+ /* First thirty-two bits of the fractional parts of the square
+ * roots of the first eight prime numbers: 2, 3, 5, 7, 11, 13,
+ * 17, 19." */
+ ctx->H[0] = 0x6a09e667UL;
+ ctx->H[1] = 0xbb67ae85UL;
+ ctx->H[2] = 0x3c6ef372UL;
+ ctx->H[3] = 0xa54ff53aUL;
+ ctx->H[4] = 0x510e527fUL;
+ ctx->H[5] = 0x9b05688cUL;
+ ctx->H[6] = 0x1f83d9abUL;
+ ctx->H[7] = 0x5be0cd19UL;
+
+ /* Initialise number of bytes. */
+ ctx->count = 0;
+}
+
+
+/**
+ * Number of bytes in single SHA-256 word
+ * used to process data
+ */
+#define SHA256_BYTES_IN_WORD 4
+
+/**
+ * Base of SHA-256 transformation.
+ * Gets full 64 bytes block of data and updates hash values;
+ * @param H hash values
+ * @param data data, must be exactly 64 bytes long
+ */
+static void
+sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
+ const uint8_t data[SHA256_BLOCK_SIZE])
+{
+ /* Working variables,
+ see FIPS PUB 180-4 paragraph 6.2. */
+ uint32_t a = H[0];
+ uint32_t b = H[1];
+ uint32_t c = H[2];
+ uint32_t d = H[3];
+ uint32_t e = H[4];
+ uint32_t f = H[5];
+ uint32_t g = H[6];
+ uint32_t h = H[7];
+
+ /* Data buffer, used as cyclic buffer.
+ See FIPS PUB 180-4 paragraphs 5.2.1, 6.2. */
+ uint32_t W[16];
+
+ /* 'Ch' and 'Maj' macro functions are defined with
+ widely-used optimization.
+ See FIPS PUB 180-4 formulae 4.2, 4.3. */
+#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) )
+#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
+ /* Unoptimized (original) versions: */
+/* #define Ch(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */
+/* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
+
+ /* Four 'Sigma' macro functions.
+ See FIPS PUB 180-4 formulae 4.4, 4.5, 4.6, 4.7. */
+#define SIG0(x) (_MHD_ROTR32 ((x),2) ^ _MHD_ROTR32 ((x),13) ^ _MHD_ROTR32 ((x), \
+ 22) )
+#define SIG1(x) (_MHD_ROTR32 ((x),6) ^ _MHD_ROTR32 ((x),11) ^ _MHD_ROTR32 ((x), \
+ 25) )
+#define sig0(x) (_MHD_ROTR32 ((x),7) ^ _MHD_ROTR32 ((x),18) ^ ((x) >> 3) )
+#define sig1(x) (_MHD_ROTR32 ((x),17) ^ _MHD_ROTR32 ((x),19) ^ ((x) >> 10) )
+
+ /* Single step of SHA-256 computation,
+ see FIPS PUB 180-4 paragraph 6.2.2 step 3.
+ * Note: instead of reassigning all working variables on each step,
+ variables are rotated for each step:
+ SHA2STEP32(a, b, c, d, e, f, g, h, K[0], data[0]);
+ SHA2STEP32(h, a, b, c, d, e, f, g, K[1], data[1]);
+ so current 'vD' will be used as 'vE' on next step,
+ current 'vH' will be used as 'vA' on next step.
+ * Note: first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in FIPS PUB 180-4 paragraph 6.2.2 step 3.
+ second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in FIPS PUB 180-4 paragraph 6.2.2 step 3.
+ * Note: 'wt' must be used exactly one time in this macro as it change other data as well
+ every time when used. */
+#define SHA2STEP32(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \
+ (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \
+ (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0)
+
+ /* Get value of W(t) from input data buffer,
+ See FIPS PUB 180-4 paragraph 6.2.
+ Input data must be read in big-endian bytes order,
+ see FIPS PUB 180-4 paragraph 3.1.2. */
+#define GET_W_FROM_DATA(buf,t) \
+ _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA256_BYTES_IN_WORD)
+
+ /* During first 16 steps, before making any calculations on each step,
+ the W element is read from input data buffer as big-endian value and
+ stored in array of W elements. */
+ /* Note: instead of using K constants as array, all K values are specified
+ individually for each step, see FIPS PUB 180-4 paragraph 4.2.2 for K values. */
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0x428a2f98UL, W[0] = GET_W_FROM_DATA (
+ data,0));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0x71374491UL, W[1] = GET_W_FROM_DATA (
+ data,1));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0xb5c0fbcfUL, W[2] = GET_W_FROM_DATA (
+ data,2));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0xe9b5dba5UL, W[3] = GET_W_FROM_DATA (
+ data,3));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x3956c25bUL, W[4] = GET_W_FROM_DATA (
+ data,4));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0x59f111f1UL, W[5] = GET_W_FROM_DATA (
+ data,5));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x923f82a4UL, W[6] = GET_W_FROM_DATA (
+ data,6));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0xab1c5ed5UL, W[7] = GET_W_FROM_DATA (
+ data,7));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0xd807aa98UL, W[8] = GET_W_FROM_DATA (
+ data,8));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0x12835b01UL, W[9] = GET_W_FROM_DATA (
+ data,9));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0x243185beUL, W[10] = GET_W_FROM_DATA (
+ data,10));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0x550c7dc3UL, W[11] = GET_W_FROM_DATA (
+ data,11));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x72be5d74UL, W[12] = GET_W_FROM_DATA (
+ data,12));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0x80deb1feUL, W[13] = GET_W_FROM_DATA (
+ data,13));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x9bdc06a7UL, W[14] = GET_W_FROM_DATA (
+ data,14));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0xc19bf174UL, W[15] = GET_W_FROM_DATA (
+ data,15));
+
+ /* 'W' generation and assignment for 16 <= t <= 63.
+ See FIPS PUB 180-4 paragraph 6.2.2.
+ As only last 16 'W' are used in calculations, it is possible to
+ use 16 elements array of W as cyclic buffer.
+ * Note: ((t-16)&0xf) have same value as (t&0xf) */
+#define Wgen(w,t) ( (w)[(t - 16) & 0xf] + sig1 ((w)[((t) - 2) & 0xf]) \
+ + (w)[((t) - 7) & 0xf] + sig0 ((w)[((t) - 15) & 0xf]) )
+
+ /* During last 48 steps, before making any calculations on each step,
+ W element is generated from W elements of cyclic buffer and generated value
+ stored back in cyclic buffer. */
+ /* Note: instead of using K constants as array, all K values are specified
+ individually for each step, see FIPS PUB 180-4 paragraph 4.2.2 for K values. */
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0xe49b69c1UL, W[16 & 0xf] = Wgen (W,16));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0xefbe4786UL, W[17 & 0xf] = Wgen (W,17));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0x0fc19dc6UL, W[18 & 0xf] = Wgen (W,18));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0x240ca1ccUL, W[19 & 0xf] = Wgen (W,19));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x2de92c6fUL, W[20 & 0xf] = Wgen (W,20));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0x4a7484aaUL, W[21 & 0xf] = Wgen (W,21));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x5cb0a9dcUL, W[22 & 0xf] = Wgen (W,22));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0x76f988daUL, W[23 & 0xf] = Wgen (W,23));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0x983e5152UL, W[24 & 0xf] = Wgen (W,24));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0xa831c66dUL, W[25 & 0xf] = Wgen (W,25));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0xb00327c8UL, W[26 & 0xf] = Wgen (W,26));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0xbf597fc7UL, W[27 & 0xf] = Wgen (W,27));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0xc6e00bf3UL, W[28 & 0xf] = Wgen (W,28));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0xd5a79147UL, W[29 & 0xf] = Wgen (W,29));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x06ca6351UL, W[30 & 0xf] = Wgen (W,30));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0x14292967UL, W[31 & 0xf] = Wgen (W,31));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0x27b70a85UL, W[32 & 0xf] = Wgen (W,32));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0x2e1b2138UL, W[33 & 0xf] = Wgen (W,33));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0x4d2c6dfcUL, W[34 & 0xf] = Wgen (W,34));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0x53380d13UL, W[35 & 0xf] = Wgen (W,35));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x650a7354UL, W[36 & 0xf] = Wgen (W,36));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0x766a0abbUL, W[37 & 0xf] = Wgen (W,37));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x81c2c92eUL, W[38 & 0xf] = Wgen (W,38));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0x92722c85UL, W[39 & 0xf] = Wgen (W,39));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0xa2bfe8a1UL, W[40 & 0xf] = Wgen (W,40));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0xa81a664bUL, W[41 & 0xf] = Wgen (W,41));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0xc24b8b70UL, W[42 & 0xf] = Wgen (W,42));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0xc76c51a3UL, W[43 & 0xf] = Wgen (W,43));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0xd192e819UL, W[44 & 0xf] = Wgen (W,44));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0xd6990624UL, W[45 & 0xf] = Wgen (W,45));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0xf40e3585UL, W[46 & 0xf] = Wgen (W,46));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0x106aa070UL, W[47 & 0xf] = Wgen (W,47));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0x19a4c116UL, W[48 & 0xf] = Wgen (W,48));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0x1e376c08UL, W[49 & 0xf] = Wgen (W,49));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0x2748774cUL, W[50 & 0xf] = Wgen (W,50));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0x34b0bcb5UL, W[51 & 0xf] = Wgen (W,51));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x391c0cb3UL, W[52 & 0xf] = Wgen (W,52));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0x4ed8aa4aUL, W[53 & 0xf] = Wgen (W,53));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0x5b9cca4fUL, W[54 & 0xf] = Wgen (W,54));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0x682e6ff3UL, W[55 & 0xf] = Wgen (W,55));
+ SHA2STEP32 (a, b, c, d, e, f, g, h, 0x748f82eeUL, W[56 & 0xf] = Wgen (W,56));
+ SHA2STEP32 (h, a, b, c, d, e, f, g, 0x78a5636fUL, W[57 & 0xf] = Wgen (W,57));
+ SHA2STEP32 (g, h, a, b, c, d, e, f, 0x84c87814UL, W[58 & 0xf] = Wgen (W,58));
+ SHA2STEP32 (f, g, h, a, b, c, d, e, 0x8cc70208UL, W[59 & 0xf] = Wgen (W,59));
+ SHA2STEP32 (e, f, g, h, a, b, c, d, 0x90befffaUL, W[60 & 0xf] = Wgen (W,60));
+ SHA2STEP32 (d, e, f, g, h, a, b, c, 0xa4506cebUL, W[61 & 0xf] = Wgen (W,61));
+ SHA2STEP32 (c, d, e, f, g, h, a, b, 0xbef9a3f7UL, W[62 & 0xf] = Wgen (W,62));
+ SHA2STEP32 (b, c, d, e, f, g, h, a, 0xc67178f2UL, W[63 & 0xf] = Wgen (W,63));
+
+ /* Compute intermediate hash.
+ See FIPS PUB 180-4 paragraph 4.2.2 step 4. */
+ H[0] += a;
+ H[1] += b;
+ H[2] += c;
+ H[3] += d;
+ H[4] += e;
+ H[5] += f;
+ H[6] += g;
+ H[7] += h;
+}
+
+
+/**
+ * Process portion of bytes.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param data bytes to add to hash
+ * @param length number of bytes in @a data
+ */
+void
+MHD_SHA256_update (void *ctx_,
+ const uint8_t *data,
+ size_t length)
+{
+ struct sha256_ctx *const ctx = ctx_;
+ unsigned bytes_have; /**< Number of bytes in buffer */
+
+ mhd_assert ((data != NULL) || (length == 0));
+
+ if (0 == length)
+ return; /* Do nothing */
+
+ /* Note: (count & (SHA256_BLOCK_SIZE-1))
+ equal (count % SHA256_BLOCK_SIZE) for this block size. */
+ bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1));
+ ctx->count += length;
+
+ if (0 != bytes_have)
+ {
+ unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have;
+ if (length >= bytes_left)
+ { /* Combine new data with data in buffer and
+ process full block. */
+ memcpy (ctx->buffer + bytes_have,
+ data,
+ bytes_left);
+ data += bytes_left;
+ length -= bytes_left;
+ sha256_transform (ctx->H, ctx->buffer);
+ bytes_have = 0;
+ }
+ }
+
+ while (SHA256_BLOCK_SIZE <= length)
+ { /* Process any full blocks of new data directly,
+ without copying to buffer. */
+ sha256_transform (ctx->H, data);
+ data += SHA256_BLOCK_SIZE;
+ length -= SHA256_BLOCK_SIZE;
+ }
+
+ if (0 != length)
+ { /* Copy incomplete block of new data (if any)
+ to buffer. */
+ memcpy (ctx->buffer + bytes_have, data, length);
+ }
+}
+
+
+/**
+ * Size of "length" padding addition in bytes.
+ * See FIPS PUB 180-4 paragraph 5.1.1.
+ */
+#define SHA256_SIZE_OF_LEN_ADD (64 / 8)
+
+/**
+ * Finalise SHA256 calculation, return digest.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes
+ */
+void
+sha256_finish (void *ctx_,
+ uint8_t digest[SHA256_DIGEST_SIZE])
+{
+ struct sha256_ctx *const ctx = ctx_;
+ uint64_t num_bits; /**< Number of processed bits */
+ unsigned bytes_have; /**< Number of bytes in buffer */
+
+ num_bits = ctx->count << 3;
+ /* Note: (count & (SHA256_BLOCK_SIZE-1))
+ equal (count % SHA256_BLOCK_SIZE) for this block size. */
+ bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1));
+
+ /* Input data must be padded with bit "1" and with length of data in bits.
+ See FIPS PUB 180-4 paragraph 5.1.1. */
+ /* Data is always processed in form of bytes (not by individual bits),
+ therefore position of first padding bit in byte is always predefined (0x80). */
+ /* Buffer always have space at least for one byte (as full buffers are
+ processed immediately). */
+ ctx->buffer[bytes_have++] = 0x80;
+
+ if (SHA256_BLOCK_SIZE - bytes_have < SHA256_SIZE_OF_LEN_ADD)
+ { /* No space in current block to put total length of message.
+ Pad current block with zeros and process it. */
+ while (bytes_have < SHA256_BLOCK_SIZE)
+ ctx->buffer[bytes_have++] = 0;
+ /* Process full block. */
+ sha256_transform (ctx->H, ctx->buffer);
+ /* Start new block. */
+ bytes_have = 0;
+ }
+
+ /* Pad the rest of the buffer with zeros. */
+ memset (ctx->buffer + bytes_have, 0,
+ SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have);
+ /* Put number of bits in processed message as big-endian value. */
+ _MHD_PUT_64BIT_BE (ctx->buffer + SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD,
+ num_bits);
+ /* Process full final block. */
+ sha256_transform (ctx->H, ctx->buffer);
+
+ /* Put final hash/digest in BE mode */
+ _MHD_PUT_32BIT_BE (digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]);
+ _MHD_PUT_32BIT_BE (digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]);
+ _MHD_PUT_32BIT_BE (digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]);
+ _MHD_PUT_32BIT_BE (digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]);
+ _MHD_PUT_32BIT_BE (digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]);
+ _MHD_PUT_32BIT_BE (digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]);
+ _MHD_PUT_32BIT_BE (digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]);
+ _MHD_PUT_32BIT_BE (digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]);
+
+ /* Erase potentially sensitive data. */
+ memset (ctx, 0, sizeof(struct sha256_ctx));
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/sha256.h
^
|
@@ -0,0 +1,93 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library.
+ If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/sha256.h
+ * @brief Calculation of SHA-256 digest
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_SHA256_H
+#define MHD_SHA256_H 1
+
+#include "mhd_options.h"
+#include <stdint.h>
+#include <stddef.h>
+
+/**
+ * Digest is kept internally as 8 32-bit words.
+ */
+#define _SHA256_DIGEST_LENGTH 8
+
+/**
+ * Size of SHA-256 digest in bytes
+ */
+#define SHA256_DIGEST_SIZE (_SHA256_DIGEST_LENGTH * 4)
+
+/**
+ * Size of SHA-256 digest string in chars
+ */
+#define SHA256_DIGEST_STRING_SIZE ((SHA256_DIGEST_SIZE) * 2 + 1)
+
+/**
+ * Size of single processing block in bytes
+ */
+#define SHA256_BLOCK_SIZE 64
+
+
+struct sha256_ctx
+{
+ uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
+ uint64_t count; /**< number of bytes, mod 2^64 */
+ uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */
+};
+
+/**
+ * Initialise structure for SHA256 calculation.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ */
+void
+MHD_SHA256_init (void *ctx_);
+
+
+/**
+ * Process portion of bytes.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param data bytes to add to hash
+ * @param length number of bytes in @a data
+ */
+void
+MHD_SHA256_update (void *ctx_,
+ const uint8_t *data,
+ size_t length);
+
+
+/**
+ * Finalise SHA256 calculation, return digest.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes
+ */
+void
+sha256_finish (void *ctx_,
+ uint8_t digest[SHA256_DIGEST_SIZE]);
+
+#endif /* MHD_SHA256_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/sysfdsetsize.c
^
|
@@ -56,7 +56,7 @@
#include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && ! defined(__CYGWIN__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif /* !WIN32_LEAN_AND_MEAN */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_daemon.c
^
|
@@ -43,33 +43,38 @@
d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0, NULL, NULL, NULL, NULL);
if (NULL != d)
{
+ MHD_stop_daemon (d);
fprintf (stderr,
- "Succeeded at binding to port 0?\n");
+ "Succeeded to start without MHD_AccessHandlerCallback?\n");
return 1;
}
return 0;
}
-static int
+static enum MHD_Result
apc_nothing (void *cls,
const struct sockaddr *addr,
socklen_t addrlen)
{
+ (void) cls; (void) addr; (void) addrlen; /* Unused. Silent compiler warning. */
+
return MHD_NO;
}
-static int
+static enum MHD_Result
apc_all (void *cls,
const struct sockaddr *addr,
socklen_t addrlen)
{
+ (void) cls; (void) addr; (void) addrlen; /* Unused. Silent compiler warning. */
+
return MHD_YES;
}
-static int
+static enum MHD_Result
ahc_nothing (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -78,6 +83,10 @@
const char *upload_data, size_t *upload_data_size,
void **unused)
{
+ (void) cls; (void) connection; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
+
return MHD_NO;
}
@@ -88,7 +97,7 @@
struct MHD_Daemon *d;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080,
+ 0,
&apc_nothing, NULL,
&ahc_nothing, NULL,
MHD_OPTION_END);
@@ -96,7 +105,7 @@
{
fprintf (stderr,
"Failed to start daemon on port %u\n",
- 1080);
+ 0);
exit (77);
}
MHD_stop_daemon (d);
@@ -113,7 +122,7 @@
int i;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1081,
+ 0,
&apc_all, NULL,
&ahc_nothing, NULL,
MHD_OPTION_END);
@@ -122,30 +131,30 @@
{
fprintf (stderr,
"Failed to start daemon on port %u\n",
- 1081);
+ 0);
exit (77);
}
i = 0;
while (i < 15)
+ {
+ maxfd = 0;
+ FD_ZERO (&rs);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &rs, &rs, &maxfd))
{
- maxfd = 0;
- FD_ZERO (&rs);
- if (MHD_YES != MHD_get_fdset (d, &rs, &rs, &rs, &maxfd))
- {
- MHD_stop_daemon (d);
- fprintf (stderr,
- "Failed in MHD_get_fdset()\n");
- return 256;
- }
- if (MHD_run (d) == MHD_NO)
- {
- MHD_stop_daemon (d);
- fprintf (stderr,
- "Failed in MHD_run()\n");
- return 8;
- }
- i++;
+ MHD_stop_daemon (d);
+ fprintf (stderr,
+ "Failed in MHD_get_fdset().\n");
+ return 256;
+ }
+ if (MHD_run (d) == MHD_NO)
+ {
+ MHD_stop_daemon (d);
+ fprintf (stderr,
+ "Failed in MHD_run().\n");
+ return 8;
}
+ i++;
+ }
MHD_stop_daemon (d);
return 0;
}
@@ -157,7 +166,7 @@
struct MHD_Daemon *d;
d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_INTERNAL_POLLING_THREAD,
- 1082,
+ 0,
&apc_all, NULL,
&ahc_nothing, NULL,
MHD_OPTION_END);
@@ -165,16 +174,16 @@
if (NULL == d)
{
fprintf (stderr,
- "Failed to start daemon on port %u\n",
+ "Failed to start daemon on port %u.\n",
1082);
exit (77);
}
if (MHD_run (d) != MHD_NO)
- {
- fprintf (stderr,
- "Failed in MHD_run()\n");
- return 32;
- }
+ {
+ fprintf (stderr,
+ "Failed in MHD_run().\n");
+ return 32;
+ }
MHD_stop_daemon (d);
return 0;
}
@@ -185,8 +194,9 @@
{
struct MHD_Daemon *d;
- d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION,
- 1083,
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION,
+ 0,
&apc_all, NULL,
&ahc_nothing, NULL,
MHD_OPTION_END);
@@ -195,15 +205,15 @@
{
fprintf (stderr,
"Failed to start daemon on port %u\n",
- 1083);
+ 0);
exit (77);
}
if (MHD_run (d) != MHD_NO)
- {
- fprintf (stderr,
- "Failed in MHD_run()\n");
- return 128;
- }
+ {
+ fprintf (stderr,
+ "Failed in MHD_run().\n");
+ return 128;
+ }
MHD_stop_daemon (d);
return 0;
}
@@ -214,6 +224,7 @@
char *const *argv)
{
int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
errorCount += testStartError ();
errorCount += testStartStop ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_helpers.h
^
|
@@ -39,31 +39,32 @@
* name.
*/
static int
-has_in_name(const char *prog_name, const char *marker)
+has_in_name (const char *prog_name, const char *marker)
{
size_t name_pos;
size_t pos;
- if (!prog_name || !marker || !prog_name[0] || !marker[0])
+ if (! prog_name || ! marker || ! prog_name[0] || ! marker[0])
return 0;
pos = 0;
name_pos = 0;
while (prog_name[pos])
- {
- if ('/' == prog_name[pos])
- name_pos = pos + 1;
-#ifdef _WIN32
- else if ('\\' == prog_name[pos])
- name_pos = pos + 1;
-#endif /* _WIN32 */
- pos++;
- }
+ {
+ if ('/' == prog_name[pos])
+ name_pos = pos + 1;
+#if defined(_WIN32) || defined(__CYGWIN__)
+ else if ('\\' == prog_name[pos])
+ name_pos = pos + 1;
+#endif /* _WIN32 || __CYGWIN__ */
+ pos++;
+ }
if (name_pos == pos)
return 0;
- return strstr(prog_name + name_pos, marker) != (char*)0;
+ return strstr (prog_name + name_pos, marker) != (char*) 0;
}
+
/**
* Check whether one of strings in array is equal to @a param.
* String @a argv[0] is ignored.
@@ -75,17 +76,17 @@
* non-zero if one of strings in @a argv is equal to @a param.
*/
static int
-has_param(int argc, char * const argv[], const char * param)
+has_param (int argc, char *const argv[], const char *param)
{
int i;
- if (!argv || !param || !param[0])
+ if (! argv || ! param || ! param[0])
return 0;
- for(i = 1; i < argc; i++)
- {
- if(argv[i] && strcmp(argv[i], param) == 0)
- return !0;
- }
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i] && (strcmp (argv[i], param) == 0) )
+ return ! 0;
+ }
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_http_reasons.c
^
|
@@ -28,104 +28,128 @@
#include "microhttpd.h"
#include "mhd_str.h"
-static int expect_result(int code, const char* expected)
+static int
+expect_result (int code, const char*expected)
{
- const char* const reason = MHD_get_reason_phrase_for(code);
- if (MHD_str_equal_caseless_(reason, expected))
+ const char*const reason = MHD_get_reason_phrase_for (code);
+ if (MHD_str_equal_caseless_ (reason, expected))
return 0;
- fprintf(stderr, "Incorrect reason returned for code %d:\n Returned: \"%s\" \tExpected: \"%s\"\n",
- code, reason, expected);
+ fprintf (stderr,
+ "Incorrect reason returned for code %d:\n Returned: \"%s\" \tExpected: \"%s\"\n",
+ code, reason, expected);
return 1;
}
-static int expect_absent(int code)
+
+static int
+expect_absent (int code)
{
- return expect_result(code, "unknown");
+ return expect_result (code, "unknown");
}
-static int test_absent_codes(void)
+
+static int
+test_absent_codes (void)
{
int errcount = 0;
- errcount += expect_absent(0);
- errcount += expect_absent(1);
- errcount += expect_absent(50);
- errcount += expect_absent(99);
- errcount += expect_absent(600);
- errcount += expect_absent(601);
- errcount += expect_absent(900);
- errcount += expect_absent(10000);
+ errcount += expect_absent (0);
+ errcount += expect_absent (1);
+ errcount += expect_absent (50);
+ errcount += expect_absent (99);
+ errcount += expect_absent (600);
+ errcount += expect_absent (601);
+ errcount += expect_absent (900);
+ errcount += expect_absent (10000);
return errcount;
}
-static int test_1xx(void)
+
+static int
+test_1xx (void)
{
int errcount = 0;
- errcount += expect_result(MHD_HTTP_CONTINUE, "continue");
- errcount += expect_result(MHD_HTTP_PROCESSING, "processing");
- errcount += expect_absent(110);
- errcount += expect_absent(190);
+ errcount += expect_result (MHD_HTTP_CONTINUE, "continue");
+ errcount += expect_result (MHD_HTTP_PROCESSING, "processing");
+ errcount += expect_absent (110);
+ errcount += expect_absent (190);
return errcount;
}
-static int test_2xx(void)
+
+static int
+test_2xx (void)
{
int errcount = 0;
- errcount += expect_result(MHD_HTTP_OK, "ok");
- errcount += expect_result(MHD_HTTP_ALREADY_REPORTED, "already reported");
- errcount += expect_absent(217);
- errcount += expect_result(MHD_HTTP_IM_USED, "im used");
- errcount += expect_absent(230);
- errcount += expect_absent(295);
+ errcount += expect_result (MHD_HTTP_OK, "ok");
+ errcount += expect_result (MHD_HTTP_ALREADY_REPORTED, "already reported");
+ errcount += expect_absent (217);
+ errcount += expect_result (MHD_HTTP_IM_USED, "im used");
+ errcount += expect_absent (230);
+ errcount += expect_absent (295);
return errcount;
}
-static int test_3xx(void)
+
+static int
+test_3xx (void)
{
int errcount = 0;
- errcount += expect_result(MHD_HTTP_MULTIPLE_CHOICES, "multiple choices");
- errcount += expect_result(MHD_HTTP_SEE_OTHER, "see other");
- errcount += expect_result(MHD_HTTP_PERMANENT_REDIRECT, "permanent redirect");
- errcount += expect_absent(311);
- errcount += expect_absent(399);
+ errcount += expect_result (MHD_HTTP_MULTIPLE_CHOICES, "multiple choices");
+ errcount += expect_result (MHD_HTTP_SEE_OTHER, "see other");
+ errcount += expect_result (MHD_HTTP_PERMANENT_REDIRECT, "permanent redirect");
+ errcount += expect_absent (311);
+ errcount += expect_absent (399);
return errcount;
}
-static int test_4xx(void)
+
+static int
+test_4xx (void)
{
int errcount = 0;
- errcount += expect_result(MHD_HTTP_BAD_REQUEST, "bad request");
- errcount += expect_result(MHD_HTTP_NOT_FOUND, "not found");
- errcount += expect_result(MHD_HTTP_URI_TOO_LONG, "uri too long");
- errcount += expect_result(MHD_HTTP_EXPECTATION_FAILED, "expectation failed");
- errcount += expect_result(MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, "request header fields too large");
- errcount += expect_absent(441);
- errcount += expect_result(MHD_HTTP_NO_RESPONSE, "no response");
- errcount += expect_result(MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS, "unavailable for legal reasons");
- errcount += expect_absent(470);
- errcount += expect_absent(493);
+ errcount += expect_result (MHD_HTTP_BAD_REQUEST, "bad request");
+ errcount += expect_result (MHD_HTTP_NOT_FOUND, "not found");
+ errcount += expect_result (MHD_HTTP_URI_TOO_LONG, "uri too long");
+ errcount += expect_result (MHD_HTTP_EXPECTATION_FAILED, "expectation failed");
+ errcount += expect_result (MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
+ "request header fields too large");
+ errcount += expect_absent (441);
+ errcount += expect_result (MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
+ "unavailable for legal reasons");
+ errcount += expect_absent (470);
+ errcount += expect_absent (493);
return errcount;
}
-static int test_5xx(void)
+
+static int
+test_5xx (void)
{
int errcount = 0;
- errcount += expect_result(MHD_HTTP_INTERNAL_SERVER_ERROR, "internal server error");
- errcount += expect_result(MHD_HTTP_BAD_GATEWAY, "bad gateway");
- errcount += expect_result(MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED, "http version not supported");
- errcount += expect_result(MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED, "network authentication required");
- errcount += expect_absent(520);
- errcount += expect_absent(597);
+ errcount += expect_result (MHD_HTTP_INTERNAL_SERVER_ERROR,
+ "internal server error");
+ errcount += expect_result (MHD_HTTP_BAD_GATEWAY, "bad gateway");
+ errcount += expect_result (MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED,
+ "http version not supported");
+ errcount += expect_result (MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED,
+ "network authentication required");
+ errcount += expect_absent (520);
+ errcount += expect_absent (597);
return errcount;
}
-int main(int argc, char * argv[])
+
+int
+main (int argc, char *argv[])
{
int errcount = 0;
- errcount += test_absent_codes();
- errcount += test_1xx();
- errcount += test_2xx();
- errcount += test_3xx();
- errcount += test_4xx();
- errcount += test_5xx();
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+
+ errcount += test_absent_codes ();
+ errcount += test_1xx ();
+ errcount += test_2xx ();
+ errcount += test_3xx ();
+ errcount += test_4xx ();
+ errcount += test_5xx ();
return errcount == 0 ? 0 : 1;
}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_md5.c
^
|
@@ -0,0 +1,387 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Karlson2k (Evgeny Grin)
+
+ This test tool is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or
+ (at your option) any later version.
+
+ This test tool is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/test_md5.h
+ * @brief Unit tests for md5 functions
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_options.h"
+#include "md5.h"
+#include "test_helpers.h"
+#include <stdio.h>
+
+static int verbose = 0; /* verbose level (0-1)*/
+
+
+struct str_with_len
+{
+ const char *const str;
+ const size_t len;
+};
+
+#define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
+
+struct data_unit1
+{
+ const struct str_with_len str_l;
+ const uint8_t digest[MD5_DIGEST_SIZE];
+};
+
+static const struct data_unit1 data_units1[] = {
+ {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
+ {0x1c, 0x68, 0xc2, 0xe5, 0x1f, 0x63, 0xc9, 0x5f, 0x17, 0xab, 0x1f, 0x20,
+ 0x8b, 0x86, 0x39, 0x57}},
+ {D_STR_W_LEN ("Simple string."),
+ {0xf1, 0x2b, 0x7c, 0xad, 0xa0, 0x41, 0xfe, 0xde, 0x4e, 0x68, 0x16, 0x63,
+ 0xb4, 0x60, 0x5d, 0x78}},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
+ {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c,
+ 0xca, 0x67, 0xe1, 0x3b}},
+ {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
+ {0x05, 0x61, 0x3a, 0x6b, 0xde, 0x75, 0x3a, 0x45, 0x91, 0xa8, 0x81, 0xb0,
+ 0xa7, 0xe2, 0xe2, 0x0e}},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"
+ "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
+ {0xaf, 0xab, 0xc7, 0xe9, 0xe7, 0x17, 0xbe, 0xd6, 0xc0, 0x0f, 0x78, 0x8c,
+ 0xde, 0xdd, 0x11, 0xd1}},
+};
+
+static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
+
+struct bin_with_len
+{
+ const uint8_t bin[512];
+ const size_t len;
+};
+
+struct data_unit2
+{
+ const struct bin_with_len bin_l;
+ const uint8_t digest[MD5_DIGEST_SIZE];
+};
+
+static const struct data_unit2 data_units2[] = {
+ { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
+ {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c,
+ 0xca, 0x67, 0xe1, 0x3b}},
+ { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65}, 72 },/* 'A' x 72 times */
+ {0x24, 0xa5, 0xef, 0x36, 0x82, 0x80, 0x3a, 0x06, 0x2f, 0xea, 0xad, 0xad,
+ 0x76, 0xda, 0xbd, 0xa8}},
+ { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73}, 55}, /* 19..73 sequence */
+ {0x6d, 0x2e, 0x6e, 0xde, 0x5d, 0x64, 0x6a, 0x17, 0xf1, 0x09, 0x2c, 0xac,
+ 0x19, 0x10, 0xe3, 0xd6}},
+ { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
+ {0x88, 0x13, 0x48, 0x47, 0x73, 0xaa, 0x92, 0xf2, 0xc9, 0xdd, 0x69, 0xb3,
+ 0xac, 0xf4, 0xba, 0x6e}},
+ { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92}, 55}, /* 38..92 sequence */
+ {0x80, 0xf0, 0x05, 0x7e, 0xa2, 0xf7, 0xc8, 0x43, 0x12, 0xd3, 0xb1, 0x61,
+ 0xab, 0x52, 0x3b, 0xaf}},
+ { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72},
+ 72},/* 1..72 sequence */
+ {0xc3, 0x28, 0xc5, 0xad, 0xc9, 0x26, 0xa9, 0x99, 0x95, 0x4a, 0x5e, 0x25,
+ 0x50, 0x34, 0x51, 0x73}},
+ { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160,
+ 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180,
+ 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 199, 200,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220,
+ 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 237, 238, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255}, 256}, /* 0..255 sequence */
+ {0xe2, 0xc8, 0x65, 0xdb, 0x41, 0x62, 0xbe, 0xd9, 0x63, 0xbf, 0xaa, 0x9e,
+ 0xf6, 0xac, 0x18, 0xf0}},
+ { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
+ 185, 184, 183, 182, 181, 180,
+ 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
+ 165, 164, 163, 162, 161, 160,
+ 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
+ 145, 144, 143, 142, 141, 140,
+ 139}, 61}, /* 199..139 sequence */
+ {0xbb, 0x3f, 0xdb, 0x4a, 0x96, 0x03, 0x36, 0x37, 0x38, 0x78, 0x5e, 0x44,
+ 0xbf, 0x3a, 0x85, 0x51}},
+ { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
+ 241, 240, 239, 238, 237, 236,
+ 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222,
+ 221, 220, 219, 218, 217, 216,
+ 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202,
+ 201, 200, 199, 198, 197, 196,
+ 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182,
+ 181, 180, 179, 178, 177, 176,
+ 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162,
+ 161, 160, 159, 158, 157, 156,
+ 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142,
+ 141, 140, 139, 138, 137, 136,
+ 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122,
+ 121, 120, 119, 118, 117, 116,
+ 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
+ 101, 100, 99, 98, 97, 96, 95,
+ 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77,
+ 76, 75, 74, 73, 72, 71, 70,
+ 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52,
+ 51, 50, 49, 48, 47, 46, 45,
+ 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
+ 26, 25, 24, 23, 22, 21, 20,
+ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255}, /* 255..1 sequence */
+ {0x52, 0x21, 0xa5, 0x83, 0x4f, 0x38, 0x7c, 0x73, 0xba, 0x18, 0x22, 0xb1,
+ 0xf9, 0x7e, 0xae, 0x8b}},
+ { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
+ 235, 179, 166, 219, 60, 135,
+ 12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222, 179, 18, 77, 200, 67, 187,
+ 139, 166, 31, 3, 90, 125, 9,
+ 56, 37, 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28,
+ 219, 174, 50, 32, 154, 80, 238,
+ 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220, 173, 79, 20, 242,
+ 68, 64, 102, 208, 107, 196,
+ 48, 183, 50, 59, 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202,
+ 153, 2, 185, 114, 157, 73,
+ 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191, 103,
+ 214, 191, 20, 214, 126, 45,
+ 220, 142, 102, 131, 239, 87, 73, 97, 255, 105, 143, 97, 205, 209, 30,
+ 157, 156, 22, 114, 114, 230,
+ 29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51,
+ 116, 158, 12, 244, 213,
+ 212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244, 204, 207, 211, 144,
+ 45, 72, 211, 143, 117, 230,
+ 217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212,
+ 97, 141, 190, 123, 5, 21, 7,
+ 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62, 105, 21,
+ 248, 70, 106, 4, 150, 115,
+ 14, 217, 22, 47, 103, 104, 212, 247, 74, 74, 208, 87, 104}, 255}, /* pseudo-random data */
+ {0x55, 0x61, 0x2c, 0xeb, 0x29, 0xee, 0xa8, 0xb2, 0xf6, 0x10, 0x7b, 0xc1,
+ 0x5b, 0x0f, 0x01, 0x95}}
+};
+
+static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
+
+
+/*
+ * Helper functions
+ */
+
+/**
+ * Print bin as hex
+ *
+ * @param bin binary data
+ * @param len number of bytes in bin
+ * @param hex pointer to len*2+1 bytes buffer
+ */
+static void
+bin2hex (const uint8_t *bin,
+ size_t len,
+ char *hex)
+{
+ while (len-- > 0)
+ {
+ unsigned int b1, b2;
+ b1 = (*bin >> 4) & 0xf;
+ *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
+ b2 = *bin++ & 0xf;
+ *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
+ }
+ *hex = 0;
+}
+
+
+static int
+check_result (const char *test_name,
+ unsigned int check_num,
+ const uint8_t calculated[MD5_DIGEST_SIZE],
+ const uint8_t expected[MD5_DIGEST_SIZE])
+{
+ int failed = memcmp (calculated, expected, MD5_DIGEST_SIZE);
+ check_num++; /* Print 1-based numbers */
+ if (failed)
+ {
+ char calc_str[MD5_DIGEST_STRING_LENGTH];
+ char expc_str[MD5_DIGEST_STRING_LENGTH];
+ bin2hex (calculated, MD5_DIGEST_SIZE, calc_str);
+ bin2hex (expected, MD5_DIGEST_SIZE, expc_str);
+ fprintf (stderr,
+ "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
+ test_name, check_num, calc_str, expc_str);
+ fflush (stderr);
+ }
+ else if (verbose)
+ {
+ char calc_str[MD5_DIGEST_STRING_LENGTH];
+ bin2hex (calculated, MD5_DIGEST_SIZE, calc_str);
+ printf (
+ "PASSED: %s check %u: calculated digest %s match expected digest.\n",
+ test_name, check_num, calc_str);
+ fflush (stdout);
+ }
+ return failed ? 1 : 0;
+}
+
+
+/*
+ * Tests
+ */
+
+/* Calculated MD5 as one pass for whole data */
+static int
+test1_str (void)
+{
+ unsigned int i;
+ int num_failed = 0;
+
+ for (i = 0; i < units1_num; i++)
+ {
+ struct MD5Context ctx;
+ uint8_t digest[MD5_DIGEST_SIZE];
+
+ MHD_MD5Init (&ctx);
+ MHD_MD5Update (&ctx, (const uint8_t*) data_units1[i].str_l.str,
+ data_units1[i].str_l.len);
+ MHD_MD5Final (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units1[i].digest);
+ }
+ return num_failed;
+}
+
+
+static int
+test1_bin (void)
+{
+ unsigned int i;
+ int num_failed = 0;
+
+ for (i = 0; i < units2_num; i++)
+ {
+ struct MD5Context ctx;
+ uint8_t digest[MD5_DIGEST_SIZE];
+
+ MHD_MD5Init (&ctx);
+ MHD_MD5Update (&ctx, data_units2[i].bin_l.bin, data_units2[i].bin_l.len);
+ MHD_MD5Final (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units2[i].digest);
+ }
+ return num_failed;
+}
+
+
+/* Calculated MD5 as two iterations for whole data */
+static int
+test2_str (void)
+{
+ unsigned int i;
+ int num_failed = 0;
+
+ for (i = 0; i < units1_num; i++)
+ {
+ struct MD5Context ctx;
+ uint8_t digest[MD5_DIGEST_SIZE];
+ size_t part_s = data_units1[i].str_l.len / 4;
+
+ MHD_MD5Init (&ctx);
+ MHD_MD5Update (&ctx, (const uint8_t*) data_units1[i].str_l.str, part_s);
+ MHD_MD5Update (&ctx, (const uint8_t*) data_units1[i].str_l.str + part_s,
+ data_units1[i].str_l.len - part_s);
+ MHD_MD5Final (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units1[i].digest);
+ }
+ return num_failed;
+}
+
+
+static int
+test2_bin (void)
+{
+ unsigned int i;
+ int num_failed = 0;
+
+ for (i = 0; i < units2_num; i++)
+ {
+ struct MD5Context ctx;
+ uint8_t digest[MD5_DIGEST_SIZE];
+ size_t part_s = data_units2[i].bin_l.len * 2 / 3;
+
+ MHD_MD5Init (&ctx);
+ MHD_MD5Update (&ctx, data_units2[i].bin_l.bin, part_s);
+ MHD_MD5Update (&ctx, data_units2[i].bin_l.bin + part_s,
+ data_units2[i].bin_l.len - part_s);
+ MHD_MD5Final (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units2[i].digest);
+ }
+ return num_failed;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int num_failed = 0;
+ (void) has_in_name; /* Mute compiler warning. */
+ if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
+ verbose = 1;
+
+ num_failed += test1_str ();
+ num_failed += test1_bin ();
+
+ num_failed += test2_str ();
+ num_failed += test2_bin ();
+
+ return num_failed ? 1 : 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_options.c
^
|
@@ -0,0 +1,137 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file test_options.c
+ * @brief Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include "mhd_sockets.h"
+
+#define MHD_E_MEM "Error: memory error\n"
+#define MHD_E_SERVER_INIT "Error: failed to start server\n"
+
+const int DEBUG_GNUTLS_LOG_LEVEL = 0;
+const char *test_file_name = "https_test_file";
+const char test_file_data[] = "Hello World\n";
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ (void) cls;
+ (void) connection;
+ (void) url;
+ (void) method;
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size;
+ (void) unused;
+
+ return 0;
+}
+
+
+static int
+test_wrap_loc (char *test_name, int (*test)(void))
+{
+ int ret;
+
+ fprintf (stdout, "running test: %s ", test_name);
+ ret = test ();
+ if (ret == 0)
+ {
+ fprintf (stdout, "[pass]\n");
+ }
+ else
+ {
+ fprintf (stdout, "[fail]\n");
+ }
+ return ret;
+}
+
+
+/**
+ * Test daemon initialization with the MHD_OPTION_SOCK_ADDR option
+ */
+static int
+test_ip_addr_option ()
+{
+ struct MHD_Daemon *d;
+ struct sockaddr_in daemon_ip_addr;
+#if HAVE_INET6 && defined (USE_IPV6_TESTING)
+ struct sockaddr_in6 daemon_ip_addr6;
+#endif
+
+ memset (&daemon_ip_addr, 0, sizeof (struct sockaddr_in));
+ daemon_ip_addr.sin_family = AF_INET;
+ daemon_ip_addr.sin_port = 0;
+ daemon_ip_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+
+#if HAVE_INET6 && defined (USE_IPV6_TESTING)
+ memset (&daemon_ip_addr6, 0, sizeof (struct sockaddr_in6));
+ daemon_ip_addr6.sin6_family = AF_INET6;
+ daemon_ip_addr6.sin6_port = 0;
+ daemon_ip_addr6.sin6_addr = in6addr_loopback;
+#endif
+
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG, 0,
+ NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
+ &daemon_ip_addr, MHD_OPTION_END);
+
+ if (d == 0)
+ return -1;
+
+ MHD_stop_daemon (d);
+
+#if HAVE_INET6 && defined (USE_IPV6_TESTING)
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_IPv6, 0,
+ NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
+ &daemon_ip_addr6, MHD_OPTION_END);
+
+ if (d == 0)
+ return -1;
+
+ MHD_stop_daemon (d);
+#endif
+
+ return 0;
+}
+
+
+/* setup a temporary transfer test file */
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+
+ errorCount += test_wrap_loc ("ip addr option", &test_ip_addr_option);
+
+ return errorCount != 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_postprocessor.c
^
|
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007,2013 Christian Grothoff
+ Copyright (C) 2007, 2013, 2019, 2020 Christian Grothoff
libmicrohttpd is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -17,13 +17,11 @@
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
-
/**
* @file test_postprocessor.c
* @brief Testcase for postprocessor
* @author Christian Grothoff
*/
-
#include "platform.h"
#include "microhttpd.h"
#include "internal.h"
@@ -42,19 +40,31 @@
* five NULL-entries.
*/
const char *want[] = {
+#define URL_NOVALUE1_DATA "abc&x=5"
+#define URL_NOVALUE1_START 0
+ "abc", NULL, NULL, NULL, NULL,
+ "x", NULL, NULL, NULL, "5",
+#define URL_NOVALUE1_END (URL_NOVALUE1_START + 10)
+#define URL_NOVALUE2_DATA "abc=&x=5"
+#define URL_NOVALUE2_START URL_NOVALUE1_END
+ "abc", NULL, NULL, NULL, "",
+ "x", NULL, NULL, NULL, "5",
+#define URL_NOVALUE2_END (URL_NOVALUE2_START + 10)
#define URL_DATA "abc=def&x=5"
-#define URL_START 0
+#define URL_START URL_NOVALUE2_END
"abc", NULL, NULL, NULL, "def",
"x", NULL, NULL, NULL, "5",
#define URL_END (URL_START + 10)
NULL, NULL, NULL, NULL, NULL,
-#define FORM_DATA "--AaB03x\r\ncontent-disposition: form-data; name=\"field1\"\r\n\r\nJoe Blow\r\n--AaB03x\r\ncontent-disposition: form-data; name=\"pics\"; filename=\"file1.txt\"\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nfiledata\r\n--AaB03x--\r\n"
+#define FORM_DATA \
+ "--AaB03x\r\ncontent-disposition: form-data; name=\"field1\"\r\n\r\nJoe Blow\r\n--AaB03x\r\ncontent-disposition: form-data; name=\"pics\"; filename=\"file1.txt\"\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nfiledata\r\n--AaB03x--\r\n"
#define FORM_START (URL_END + 5)
"field1", NULL, NULL, NULL, "Joe Blow",
"pics", "file1.txt", "text/plain", "binary", "filedata",
#define FORM_END (FORM_START + 10)
NULL, NULL, NULL, NULL, NULL,
-#define FORM_NESTED_DATA "--AaB03x\r\ncontent-disposition: form-data; name=\"field1\"\r\n\r\nJane Blow\r\n--AaB03x\r\ncontent-disposition: form-data; name=\"pics\"\r\nContent-type: multipart/mixed, boundary=BbC04y\r\n\r\n--BbC04y\r\nContent-disposition: attachment; filename=\"file1.txt\"\r\nContent-Type: text/plain\r\n\r\nfiledata1\r\n--BbC04y\r\nContent-disposition: attachment; filename=\"file2.gif\"\r\nContent-type: image/gif\r\nContent-Transfer-Encoding: binary\r\n\r\nfiledata2\r\n--BbC04y--\r\n--AaB03x--"
+#define FORM_NESTED_DATA \
+ "--AaB03x\r\ncontent-disposition: form-data; name=\"field1\"\r\n\r\nJane Blow\r\n--AaB03x\r\ncontent-disposition: form-data; name=\"pics\"\r\nContent-type: multipart/mixed, boundary=BbC04y\r\n\r\n--BbC04y\r\nContent-disposition: attachment; filename=\"file1.txt\"\r\nContent-Type: text/plain\r\n\r\nfiledata1\r\n--BbC04y\r\nContent-disposition: attachment; filename=\"file2.gif\"\r\nContent-type: image/gif\r\nContent-Transfer-Encoding: binary\r\n\r\nfiledata2\r\n--BbC04y--\r\n--AaB03x--"
#define FORM_NESTED_START (FORM_END + 5)
"field1", NULL, NULL, NULL, "Jane Blow",
"pics", "file1.txt", "text/plain", NULL, "filedata1",
@@ -70,6 +80,7 @@
NULL, NULL, NULL, NULL, NULL
};
+
static int
mismatch (const char *a, const char *b)
{
@@ -80,54 +91,89 @@
return 0 != strcmp (a, b);
}
-static int
+
+static enum MHD_Result
value_checker (void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *filename,
const char *content_type,
const char *transfer_encoding,
- const char *data, uint64_t off, size_t size)
+ const char *data,
+ uint64_t off,
+ size_t size)
{
int *want_off = cls;
int idx = *want_off;
+ (void) kind; /* Unused. Silent compiler warning. */
#if 0
fprintf (stderr,
- "VC: `%s' `%s' `%s' `%s' `%.*s'\n",
+ "VC: `%s' `%s' `%s' `%s' `%.*s' (%d)\n",
key, filename, content_type, transfer_encoding,
(int) size,
- data);
+ data,
+ (int) size);
#endif
if ( (0 != off) && (0 == size) )
+ {
+ if (NULL == want[idx + 4])
+ *want_off = idx + 5;
return MHD_YES;
+ }
if ((idx < 0) ||
(want[idx] == NULL) ||
(0 != strcmp (key, want[idx])) ||
(mismatch (filename, want[idx + 1])) ||
(mismatch (content_type, want[idx + 2])) ||
(mismatch (transfer_encoding, want[idx + 3])) ||
- (0 != memcmp (data, &want[idx + 4][off], size)))
- {
- *want_off = -1;
- return MHD_NO;
- }
- if (off + size == strlen (want[idx + 4]))
+ (0 != memcmp (data,
+ &want[idx + 4][off],
+ size)))
+ {
+ *want_off = -1;
+ fprintf (stderr,
+ "Failed with: `%s' `%s' `%s' `%s' `%.*s'\n",
+ key, filename, content_type, transfer_encoding,
+ (int) size,
+ data);
+ fprintf (stderr,
+ "Wanted: `%s' `%s' `%s' `%s' `%s'\n",
+ want[idx],
+ want[idx + 1],
+ want[idx + 2],
+ want[idx + 3],
+ want[idx + 4]);
+ fprintf (stderr,
+ "Unexpected result: %d/%d/%d/%d/%d/%d/%d\n",
+ (idx < 0),
+ (want[idx] == NULL),
+ (NULL != want[idx]) && (0 != strcmp (key, want[idx])),
+ (mismatch (filename, want[idx + 1])),
+ (mismatch (content_type, want[idx + 2])),
+ (mismatch (transfer_encoding, want[idx + 3])),
+ (0 != memcmp (data, &want[idx + 4][off], size)));
+ return MHD_NO;
+ }
+ if ( ( (NULL == want[idx + 4]) &&
+ (0 == off + size) ) ||
+ (off + size == strlen (want[idx + 4])) )
*want_off = idx + 5;
return MHD_YES;
-
}
static int
-test_urlencoding ()
+test_urlencoding_case (unsigned int want_start,
+ unsigned int want_end,
+ const char *url_data)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
- unsigned int want_off = URL_START;
- int i;
- int delta;
+ unsigned int want_off = want_start;
+ size_t i;
+ size_t delta;
size_t size;
memset (&connection, 0, sizeof (struct MHD_Connection));
@@ -135,26 +181,63 @@
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ header.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONTENT_TYPE);
+ header.value_size = MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_FORM_URLENCODED);
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection,
- 1024, &value_checker, &want_off);
+ 1024,
+ &value_checker,
+ &want_off);
i = 0;
- size = strlen (URL_DATA);
+ size = strlen (url_data);
while (i < size)
- {
- delta = 1 + MHD_random_ () % (size - i);
- MHD_post_process (pp, &URL_DATA[i], delta);
- i += delta;
- }
+ {
+ delta = 1 + MHD_random_ () % (size - i);
+ MHD_post_process (pp,
+ &url_data[i],
+ delta);
+ i += delta;
+ }
MHD_destroy_post_processor (pp);
- if (want_off != URL_END)
+ if (want_off != want_end)
+ {
+ fprintf (stderr,
+ "Test failed in line %u: %u != %u\n",
+ (unsigned int) __LINE__,
+ want_off,
+ want_end);
return 1;
+ }
return 0;
}
static int
-test_multipart_garbage ()
+test_urlencoding (void)
+{
+ unsigned int errorCount = 0;
+
+ errorCount += test_urlencoding_case (URL_START,
+ URL_END,
+ URL_DATA);
+ errorCount += test_urlencoding_case (URL_NOVALUE1_START,
+ URL_NOVALUE1_END,
+ URL_NOVALUE1_DATA);
+ errorCount += test_urlencoding_case (URL_NOVALUE2_START,
+ URL_NOVALUE2_END,
+ URL_NOVALUE2_DATA);
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Test failed in line %u with %u errors\n",
+ (unsigned int) __LINE__,
+ errorCount);
+ return errorCount;
+}
+
+
+static int
+test_multipart_garbage (void)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
@@ -169,8 +252,6 @@
xdata[1] = 'x';
xdata[2] = '\r';
memcpy (&xdata[3], FORM_DATA, size);
-
- size = strlen (FORM_DATA);
size += 3;
for (splitpoint = 1; splitpoint < size; splitpoint++)
{
@@ -181,6 +262,9 @@
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value =
MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
+ header.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_CONTENT_TYPE);
+ header.value_size = MHD_STATICSTR_LEN_ (
+ MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x");
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection,
1024, &value_checker, &want_off);
@@ -188,14 +272,20 @@
MHD_post_process (pp, &xdata[splitpoint], size - splitpoint);
MHD_destroy_post_processor (pp);
if (want_off != FORM_END)
+ {
+ fprintf (stderr,
+ "Test failed in line %u at point %d\n",
+ (unsigned int) __LINE__,
+ (int) splitpoint);
return (int) splitpoint;
+ }
}
return 0;
}
static int
-test_multipart_splits ()
+test_multipart_splits (void)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
@@ -214,6 +304,8 @@
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value =
MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection,
1024, &value_checker, &want_off);
@@ -221,21 +313,27 @@
MHD_post_process (pp, &FORM_DATA[splitpoint], size - splitpoint);
MHD_destroy_post_processor (pp);
if (want_off != FORM_END)
+ {
+ fprintf (stderr,
+ "Test failed in line %u at point %d\n",
+ (unsigned int) __LINE__,
+ (int) splitpoint);
return (int) splitpoint;
+ }
}
return 0;
}
static int
-test_multipart ()
+test_multipart (void)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
unsigned int want_off = FORM_START;
- int i;
- int delta;
+ size_t i;
+ size_t delta;
size_t size;
memset (&connection, 0, sizeof (struct MHD_Connection));
@@ -245,32 +343,39 @@
header.value =
MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
header.kind = MHD_HEADER_KIND;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
pp = MHD_create_post_processor (&connection,
1024, &value_checker, &want_off);
i = 0;
size = strlen (FORM_DATA);
while (i < size)
- {
- delta = 1 + MHD_random_ () % (size - i);
- MHD_post_process (pp, &FORM_DATA[i], delta);
- i += delta;
- }
+ {
+ delta = 1 + MHD_random_ () % (size - i);
+ MHD_post_process (pp, &FORM_DATA[i], delta);
+ i += delta;
+ }
MHD_destroy_post_processor (pp);
if (want_off != FORM_END)
+ {
+ fprintf (stderr,
+ "Test failed in line %u\n",
+ (unsigned int) __LINE__);
return 2;
+ }
return 0;
}
static int
-test_nested_multipart ()
+test_nested_multipart (void)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
unsigned int want_off = FORM_NESTED_START;
- int i;
- int delta;
+ size_t i;
+ size_t delta;
size_t size;
memset (&connection, 0, sizeof (struct MHD_Connection));
@@ -280,32 +385,39 @@
header.value =
MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
header.kind = MHD_HEADER_KIND;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
pp = MHD_create_post_processor (&connection,
1024, &value_checker, &want_off);
i = 0;
size = strlen (FORM_NESTED_DATA);
while (i < size)
- {
- delta = 1 + MHD_random_ () % (size - i);
- MHD_post_process (pp, &FORM_NESTED_DATA[i], delta);
- i += delta;
- }
+ {
+ delta = 1 + MHD_random_ () % (size - i);
+ MHD_post_process (pp, &FORM_NESTED_DATA[i], delta);
+ i += delta;
+ }
MHD_destroy_post_processor (pp);
if (want_off != FORM_NESTED_END)
+ {
+ fprintf (stderr,
+ "Test failed in line %u\n",
+ (unsigned int) __LINE__);
return 4;
+ }
return 0;
}
static int
-test_empty_value ()
+test_empty_value (void)
{
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
unsigned int want_off = URL_EMPTY_VALUE_START;
- int i;
- int delta;
+ size_t i;
+ size_t delta;
size_t size;
memset (&connection, 0, sizeof (struct MHD_Connection));
@@ -313,30 +425,105 @@
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection,
1024, &value_checker, &want_off);
i = 0;
size = strlen (URL_EMPTY_VALUE_DATA);
while (i < size)
- {
- delta = 1 + MHD_random_ () % (size - i);
- MHD_post_process (pp, &URL_EMPTY_VALUE_DATA[i], delta);
- i += delta;
- }
+ {
+ delta = 1 + MHD_random_ () % (size - i);
+ MHD_post_process (pp, &URL_EMPTY_VALUE_DATA[i], delta);
+ i += delta;
+ }
MHD_destroy_post_processor (pp);
if (want_off != URL_EMPTY_VALUE_END)
+ {
+ fprintf (stderr,
+ "Test failed in line %u at offset %d\n",
+ (unsigned int) __LINE__,
+ (int) want_off);
return 8;
+ }
return 0;
}
+static enum MHD_Result
+value_checker2 (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ (void) cls; (void) kind; (void) key; /* Mute compiler warnings */
+ (void) filename; (void) content_type; (void) transfer_encoding;
+ (void) data; (void) off; (void) size;
+ return MHD_YES;
+}
+
+
+static int
+test_overflow ()
+{
+ struct MHD_Connection connection;
+ struct MHD_HTTP_Header header;
+ struct MHD_PostProcessor *pp;
+ size_t i;
+ size_t j;
+ size_t delta;
+ char *buf;
+
+ memset (&connection, 0, sizeof (struct MHD_Connection));
+ memset (&header, 0, sizeof (struct MHD_HTTP_Header));
+ connection.headers_received = &header;
+ header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
+ header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
+ header.kind = MHD_HEADER_KIND;
+ for (i = 128; i < 1024 * 1024; i += 1024)
+ {
+ pp = MHD_create_post_processor (&connection,
+ 1024,
+ &value_checker2,
+ NULL);
+ buf = malloc (i);
+ if (NULL == buf)
+ return 1;
+ memset (buf, 'A', i);
+ buf[i / 2] = '=';
+ delta = 1 + (MHD_random_ () % (i - 1));
+ j = 0;
+ while (j < i)
+ {
+ if (j + delta > i)
+ delta = i - j;
+ if (MHD_NO ==
+ MHD_post_process (pp,
+ &buf[j],
+ delta))
+ break;
+ j += delta;
+ }
+ free (buf);
+ MHD_destroy_post_processor (pp);
+ }
+ return 0;
+}
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
errorCount += test_multipart_splits ();
errorCount += test_multipart_garbage ();
@@ -344,6 +531,7 @@
errorCount += test_multipart ();
errorCount += test_nested_multipart ();
errorCount += test_empty_value ();
+ errorCount += test_overflow ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
return errorCount != 0; /* 0 == pass */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_postprocessor_amp.c
^
|
@@ -5,16 +5,21 @@
#include <string.h>
#include <stdio.h>
+uint64_t num_errors;
-int check_post(void *cls, enum MHD_ValueKind kind, const char* key,
- const char* filename, const char* content_type,
- const char* content_encoding, const char* data,
- uint64_t off, size_t size)
+enum MHD_Result
+check_post (void *cls, enum MHD_ValueKind kind, const char*key,
+ const char*filename, const char*content_type,
+ const char*content_encoding, const char*data,
+ uint64_t off, size_t size)
{
- if ((0 != strcmp(key, "a")) && (0 != strcmp(key, "b")))
- {
- printf("ERROR: got unexpected '%s'\n", key);
- }
+ (void) cls; (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) content_encoding; (void) data; (void) off; (void) size; /* Unused. Silent compiler warning. */
+ if ((0 != strcmp (key, "a")) && (0 != strcmp (key, "b")))
+ {
+ printf ("ERROR: got unexpected '%s'\n", key);
+ num_errors++;
+ }
return MHD_YES;
}
@@ -26,22 +31,28 @@
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
+ const char *post =
+ "a=xx+xx+xxx+xxxxx+xxxx+xxxxxxxx+xxx+xxxxxx+xxx+xxx+xxxxxxx+xxxxx%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++--%3E%0A++++++++++++++%3Cxxxxx+xxxxx%3D%22xxx%25%22%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xxxxx%3D%22xxxxx%22%3E%0A+++++++++++++++++++%3Cxxxxx+xxxxx%3D%22xxx%25%22%3E%0A+++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++++++++++++++%3Cxx+xxxxx%3D%22xxxx%22%3E%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%22%3Exxxxx%3A%3C%2Fx%3E%0A%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%22%3Exxx%3A%3C%2Fx%3E%0A%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%3B+xxxx-xxxxxx%3A+xxxx%3B%22%3Exxxxx+xxxxx%3A%3C%2Fx%3E%0A+++++++++++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++++++%3C%2Fxxxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxxx.xx%3C%2Fxxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A++++++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxx.xx%3C%2Fxxxx%3E%0A+++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3Bxxxx-xxxxxx%3A+xxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxxx.xx%3C%2Fxxxx%3E%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++%3C%2Fxxxxx%3E%0A+++++++%3C%21--%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++xxx+xx+xxxxx+xxxxxxx+xxxxxxx%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++--%3E%0A+++%3C%2Fxxx%3E%0A%0A%0A%0A+++%3Cxxx+xxxxx%3D%22xxxxxxxxx%22+xx%3D%22xxxxxxxxx%22%3E%3C%2Fxxx%3E%0A%0A+++%3Cxxx+xx%3D%22xxxx%22+xxxxx%3D%22xxxx%22%3E%0A+++++++%3Cxxxxx+xxxxx%3D%22xxxxxxxxx%22%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xx%3D%22xxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xx%3D%22xxxxxxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxxxxxx%22%3E%3C%2Fxx%3E%0A+++++++++++++++%3Cxx+xx%3D%22xxxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xx%3D%22xxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++%3C%2Fxxxxx%3E%0A+++%3C%2Fxxx%3E%0A%3C%2Fxxx%3E%0A%0A%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A%0A%3C%2Fxxxx%3E%0A%3C%2Fxxxx%3E+&b=value";
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+ num_errors = 0;
memset (&connection, 0, sizeof (struct MHD_Connection));
memset (&header, 0, sizeof (struct MHD_HTTP_Header));
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection,
4096, &check_post, NULL);
+ if (NULL == pp)
+ return 1;
- const char* post = "a=xx+xx+xxx+xxxxx+xxxx+xxxxxxxx+xxx+xxxxxx+xxx+xxx+xxxxxxx+xxxxx%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++--%3E%0A++++++++++++++%3Cxxxxx+xxxxx%3D%22xxx%25%22%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xxxxx%3D%22xxxxx%22%3E%0A+++++++++++++++++++%3Cxxxxx+xxxxx%3D%22xxx%25%22%3E%0A+++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++++++++++++++%3Cxx+xxxxx%3D%22xxxx%22%3E%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%22%3Exxxxx%3A%3C%2Fx%3E%0A%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%22%3Exxx%3A%3C%2Fx%3E%0A%0A+++++++++++++++++++++++++++++++%3Cx+xxxxx%3D%22xxxx-xxxxx%3Axxxxx%3B+xxxx-xxxxxx%3A+xxxx%3B%22%3Exxxxx+xxxxx%3A%3C%2Fx%3E%0A+++++++++++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++++++%3C%2Fxxxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxxx.xx%3C%2Fxxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A++++++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxx.xx%3C%2Fxxxx%3E%0A+++++++++++++++++++%3C%2Fxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A++++++++++++++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxx%3D%22xxxx-xxxxx%3A+xxxxx%3Bxxxx-xxxxxx%3A+xxxx%3B+xxxxx%3A+xxxx%22%3E%26xxxxx%3B+%3Cxxxx%0A+++++++++++++++++++++++xxxxx%3D%22xxxxxxxxxxxxxxx%22%3Exxxx.xx%3C%2Fxxxx%3E%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++%3C%2Fxxxxx%3E%0A+++++++%3C%21--%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++xxx+xx+xxxxx+xxxxxxx+xxxxxxx%0A+++++++xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0A+++++++--%3E%0A+++%3C%2Fxxx%3E%0A%0A%0A%0A+++%3Cxxx+xxxxx%3D%22xxxxxxxxx%22+xx%3D%22xxxxxxxxx%22%3E%3C%2Fxxx%3E%0A%0A+++%3Cxxx+xx%3D%22xxxx%22+xxxxx%3D%22xxxx%22%3E%0A+++++++%3Cxxxxx+xxxxx%3D%22xxxxxxxxx%22%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xx%3D%22xxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xx%3D%22xxxxxxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxxxxxx%22%3E%3C%2Fxx%3E%0A+++++++++++++++%3Cxx+xx%3D%22xxxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++++++%3Cxx%3E%0A+++++++++++++++%3Cxx+xxxxxxx%3D%22x%22+xx%3D%22xxxxxxxxxxxxx%22+xxxxx%3D%22xxxxxxxxxxxxx%22%3E%0A+++++++++++++++++++%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A+++++++++++++++%3C%2Fxx%3E%0A+++++++++++%3C%2Fxx%3E%0A+++++++%3C%2Fxxxxx%3E%0A+++%3C%2Fxxx%3E%0A%3C%2Fxxx%3E%0A%0A%3Cxxx+xx%3D%22xxxxxx%22%3E%3C%2Fxxx%3E%0A%0A%3C%2Fxxxx%3E%0A%3C%2Fxxxx%3E+&b=value";
-
- MHD_post_process (pp, post, strlen(post));
+ if (MHD_YES != MHD_post_process (pp, post, strlen (post)))
+ num_errors++;
MHD_destroy_post_processor (pp);
- return 0;
+ return num_errors == 0 ? 0 : 2;
}
-
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_postprocessor_large.c
^
|
@@ -33,7 +33,7 @@
#include <unistd.h>
#endif
-static int
+static enum MHD_Result
value_checker (void *cls,
enum MHD_ValueKind kind,
const char *key,
@@ -43,6 +43,8 @@
const char *data, uint64_t off, size_t size)
{
unsigned int *pos = cls;
+ (void) kind; (void) key; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; (void) data; (void) off; /* Unused. Silent compiler warning. */
#if 0
fprintf (stderr,
"VC: %llu %u `%s' `%s' `%s' `%s' `%.*s'\n",
@@ -63,8 +65,8 @@
struct MHD_Connection connection;
struct MHD_HTTP_Header header;
struct MHD_PostProcessor *pp;
- int i;
- int delta;
+ size_t i;
+ size_t delta;
size_t size;
char data[102400];
unsigned int pos;
@@ -78,26 +80,30 @@
connection.headers_received = &header;
header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ header.header_size = strlen (header.header);
+ header.value_size = strlen (header.value);
header.kind = MHD_HEADER_KIND;
pp = MHD_create_post_processor (&connection, 1024, &value_checker, &pos);
i = 0;
size = strlen (data);
while (i < size)
- {
- delta = 1 + MHD_random_ () % (size - i);
- MHD_post_process (pp, &data[i], delta);
- i += delta;
- }
+ {
+ delta = 1 + MHD_random_ () % (size - i);
+ MHD_post_process (pp, &data[i], delta);
+ i += delta;
+ }
MHD_destroy_post_processor (pp);
if (pos != sizeof (data) - 5) /* minus 0-termination and 'key=' */
return 1;
return 0;
}
+
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
errorCount += test_simple_large ();
if (errorCount != 0)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_postprocessor_md.c
^
|
@@ -0,0 +1,367 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2020 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file test_postprocessor.c
+ * @brief Testcase for postprocessor, keys with no value
+ * @author Markus Doppelbauer
+ */
+#include "MHD_config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <microhttpd.h>
+
+#define DEBUG 0
+
+#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
+
+/**
+ * Handler for fatal errors.
+ */
+MHD_PanicCallback mhd_panic;
+
+/**
+ * Closure argument for #mhd_panic.
+ */
+void *mhd_panic_cls;
+
+
+enum MHD_Result
+MHD_lookup_connection_value_n (struct MHD_Connection *connection,
+ enum MHD_ValueKind kind,
+ const char *key,
+ size_t key_size,
+ const char **value_ptr,
+ size_t *value_size_ptr)
+{
+ (void) connection; (void) kind; (void) key; /* Mute compiler warnings */
+ (void) key_size; (void) value_ptr; (void) value_size_ptr;
+ return MHD_NO;
+}
+
+
+#include "mhd_str.c"
+#include "internal.c"
+#include "postprocessor.c"
+
+
+static unsigned int found;
+
+
+static enum MHD_Result
+post_data_iterator (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ (void) cls; (void) kind; (void) filename; /* Mute compiler warnings */
+ (void) content_type; (void) transfer_encoding;
+ (void) off; /* FIXME: shouldn't be checked? */
+#if DEBUG
+ fprintf (stderr,
+ "%s\t%s\n",
+ key,
+ data);
+#endif
+ if (0 == strcmp (key, "xxxx"))
+ {
+ if ( (4 != size) ||
+ (0 != memcmp (data, "xxxx", 4)) )
+ exit (1);
+ found |= 1;
+ }
+ if (0 == strcmp (key, "yyyy"))
+ {
+ if ( (4 != size) ||
+ (0 != memcmp (data, "yyyy", 4)) )
+ exit (1);
+ found |= 2;
+ }
+ if (0 == strcmp (key, "zzzz"))
+ {
+ if (0 != size)
+ exit (1);
+ found |= 4;
+ }
+ if (0 == strcmp (key, "aaaa"))
+ {
+ if (0 != size)
+ exit (1);
+ found |= 8;
+ }
+ return MHD_YES;
+}
+
+
+static enum MHD_Result
+post_data_iterator2 (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ static char seen[16];
+ (void) cls; (void) kind; (void) filename; /* Mute compiler warnings */
+ (void) content_type; (void) transfer_encoding;
+
+#if DEBUG
+ printf ("%s\t%s@ %llu\n",
+ key,
+ data,
+ (unsigned long long) off);
+#endif
+ if (0 == strcmp (key, "text"))
+ {
+ if (off + size > sizeof (seen))
+ exit (6);
+ memcpy (&seen[off],
+ data,
+ size);
+ if ( (10 == off + size) &&
+ (0 == memcmp (seen, "text, text", 10)) )
+ found |= 1;
+ }
+ return MHD_YES;
+}
+
+
+static enum MHD_Result
+post_data_iterator3 (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ (void) cls; (void) kind; (void) filename; /* Mute compiler warnings */
+ (void) content_type; (void) transfer_encoding;
+ (void) off; /* FIXME: shouldn't be checked? */
+#if DEBUG
+ fprintf (stderr,
+ "%s\t%s\n",
+ key,
+ data);
+#endif
+ if (0 == strcmp (key, "y"))
+ {
+ if ( (1 != size) ||
+ (0 != memcmp (data, "y", 1)) )
+ exit (1);
+ found |= 1;
+ }
+ return MHD_YES;
+}
+
+
+static enum MHD_Result
+post_data_iterator4 (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ (void) cls; (void) kind; (void) key; /* Mute compiler warnings */
+ (void) filename; (void) content_type; (void) transfer_encoding;
+ (void) off; /* FIXME: shouldn't be checked? */
+#if DEBUG
+ fprintf (stderr,
+ "%s\t%s\n",
+ key,
+ data);
+#endif
+ if (NULL != memchr (data, 'M', size))
+ {
+ found |= 1;
+ }
+ return MHD_YES;
+}
+
+
+static enum MHD_Result
+post_data_iterator5 (void *cls,
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *filename,
+ const char *content_type,
+ const char *transfer_encoding,
+ const char *data,
+ uint64_t off,
+ size_t size)
+{
+ (void) cls; (void) kind; (void) key; /* Mute compiler warnings */
+ (void) filename; (void) content_type; (void) transfer_encoding;
+ (void) data; (void) off; (void) size;
+
+ found++;
+ return MHD_YES;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ struct MHD_PostProcessor *postprocessor;
+ (void) argc; (void) argv;
+
+ {
+ postprocessor = malloc (sizeof (struct MHD_PostProcessor)
+ + 0x1000 + 1);
+ if (NULL == postprocessor)
+ return 77;
+ memset (postprocessor,
+ 0,
+ sizeof (struct MHD_PostProcessor) + 0x1000 + 1);
+ postprocessor->ikvi = &post_data_iterator;
+ postprocessor->encoding = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ postprocessor->buffer_size = 0x1000;
+ postprocessor->state = PP_Init;
+ postprocessor->skip_rn = RN_Inactive;
+ MHD_post_process (postprocessor, "xxxx=xxxx", 9);
+ MHD_post_process (postprocessor, "&yyyy=yyyy&zzzz=&aaaa=", 22);
+ MHD_post_process (postprocessor, "", 0);
+ if (MHD_YES !=
+ MHD_destroy_post_processor (postprocessor))
+ exit (3);
+ if (found != 15)
+ exit (2);
+ }
+ {
+ found = 0;
+ postprocessor = malloc (sizeof (struct MHD_PostProcessor)
+ + 0x1000 + 1);
+ if (NULL == postprocessor)
+ return 77;
+ memset (postprocessor,
+ 0,
+ sizeof (struct MHD_PostProcessor) + 0x1000 + 1);
+ postprocessor->ikvi = post_data_iterator2;
+ postprocessor->encoding = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ postprocessor->buffer_size = 0x1000;
+ postprocessor->state = PP_Init;
+ postprocessor->skip_rn = RN_Inactive;
+ MHD_post_process (postprocessor, "text=text%2", 11);
+ MHD_post_process (postprocessor, "C+text", 6);
+ MHD_post_process (postprocessor, "", 0);
+ MHD_destroy_post_processor (postprocessor);
+ if (found != 1)
+ exit (4);
+ }
+ {
+ found = 0;
+ postprocessor = malloc (sizeof (struct MHD_PostProcessor)
+ + 0x1000 + 1);
+ if (NULL == postprocessor)
+ return 77;
+ memset (postprocessor,
+ 0,
+ sizeof (struct MHD_PostProcessor) + 0x1000 + 1);
+ postprocessor->ikvi = post_data_iterator3;
+ postprocessor->encoding = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ postprocessor->buffer_size = 0x1000;
+ postprocessor->state = PP_Init;
+ postprocessor->skip_rn = RN_Inactive;
+ {
+ const char *chunk =
+ "x=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxx%2C%2Cxxxxxx%2Cxxxx%2C%2Cxxxxx%2Cxxxxxxxxx%2C%2Cxxx%2Cxxxxxxxxxxx_xxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxx%2C%2Cx%2Cxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxx%2C%2Cx%2Cxx%2C%2Cxxxx%2Cxxx%2C%2Cx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxx%2Cxxxxxx%2Cxxxxxxxxx%2Cxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cx%2C%2Cx%2Cxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxx%2C%2C%2Cxxxxxxxxx%2Cxxxxxxxx%2C"
+ "&y=y&z=z";
+
+ MHD_post_process (postprocessor, chunk, strlen (chunk) );
+ }
+ MHD_post_process (postprocessor, "", 0);
+ MHD_destroy_post_processor (postprocessor);
+ if (found != 1)
+ exit (5);
+ }
+
+ {
+ const char *chunks[] = {
+ "t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxx%2C%2Cx%2Cxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxx%2C%2Cx%2Cxx%2C%2Cxxxx%2Cxxx%2C%2Cx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxx",
+ /* one chunk: second line is dropped */
+ "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cx%2C%2Cx%2Cxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2Cx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxx%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxxx%2Cxxxxxxxxxx%2Cxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxx%2Cxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxx%2Cxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxx%2Cx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cx%2Cxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxx%2Cxxxxxx%2Cxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxx%2C%2Cxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2C%2C%2C%2C%2C%2C%2Cxxxxxxxxxxxxxx%2C%2C%2C%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%2CxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxZZZZZZZZZZZZZ%2C%2C%2C%2C"
+ "%E2%80%A2MMMMMMMM%2C%2C%2C%2CMMMMMMMMMMMMMMMMMMMM%2CMMMMMMMMMMMMMMMMMMMMMMM%2CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM%2C%2C%2C%2CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM%2CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM%2CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"
+ "zz",
+ "",
+ };
+ postprocessor = malloc (sizeof(struct MHD_PostProcessor) + 131076 + 1);
+ if (NULL == postprocessor)
+ return 77;
+ memset (postprocessor,
+ 0,
+ sizeof (struct MHD_PostProcessor) + 0x1000 + 1);
+ postprocessor->ikvi = post_data_iterator4;
+ postprocessor->encoding = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ postprocessor->buffer_size = 131076;
+ postprocessor->state = PP_Init;
+ postprocessor->skip_rn = RN_Inactive;
+ for (unsigned i = 0; i < ARRAY_LENGTH (chunks); ++i)
+ {
+ const char *chunk = chunks[i];
+ MHD_post_process (postprocessor, chunk, strlen (chunk) );
+ }
+ MHD_destroy_post_processor (postprocessor);
+ if (found != 1)
+ return 6;
+ }
+ {
+ const char *chunks[] = {
+ "XXXXXXXXXXXX=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&XXXXXX=&XXXXXXXXXXXXXX=XXXX+&XXXXXXXXXXXXXXX=XXXXXXXXX&XXXXXXXXXXXXX=XXXX%XX%XXXXXX&XXXXXXXXXXX=XXXXXXXXX&XXXXXXXXXXXXX=XXXXXXXXXX&XXXXXXXXXXXXXXX=XX&XXXXXXXXXXXXXXX=XXXXXXXXX&XXXXXXXXXXXXX=XXXXXX&XXXXXXXXXXX=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "&XXXXXXXX=XXXX",
+ "",
+ };
+ postprocessor = malloc (sizeof(struct MHD_PostProcessor) + 131076 + 1);
+ found = 0;
+ if (NULL == postprocessor)
+ return 77;
+ memset (postprocessor,
+ 0,
+ sizeof (struct MHD_PostProcessor) + 0x1000 + 1);
+ postprocessor->ikvi = post_data_iterator5;
+ postprocessor->encoding = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
+ postprocessor->buffer_size = 131076;
+ postprocessor->state = PP_Init;
+ postprocessor->skip_rn = RN_Inactive;
+ for (unsigned i = 0; i < ARRAY_LENGTH (chunks); ++i)
+ {
+ const char *chunk = chunks[i];
+ MHD_post_process (postprocessor, chunk, strlen (chunk) );
+ }
+ MHD_destroy_post_processor (postprocessor);
+ if (found != 12)
+ return 7;
+ }
+
+
+ return EXIT_SUCCESS;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_sha256.c
^
|
@@ -0,0 +1,434 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2019 Karlson2k (Evgeny Grin)
+
+ This test tool is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or
+ (at your option) any later version.
+
+ This test tool is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file microhttpd/test_sha256.h
+ * @brief Unit tests for SHA-256 functions
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_options.h"
+#include "sha256.h"
+#include "test_helpers.h"
+#include <stdio.h>
+
+static int verbose = 0; /* verbose level (0-1)*/
+
+
+struct str_with_len
+{
+ const char *const str;
+ const size_t len;
+};
+
+#define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
+
+struct data_unit1
+{
+ const struct str_with_len str_l;
+ const uint8_t digest[SHA256_DIGEST_SIZE];
+};
+
+static const struct data_unit1 data_units1[] = {
+ {D_STR_W_LEN ("abc"),
+ {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+ 0x5d, 0xae, 0x22, 0x23,
+ 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
+ 0xf2, 0x00, 0x15, 0xad}},
+ {D_STR_W_LEN ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
+ {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93,
+ 0x0c, 0x3e, 0x60, 0x39,
+ 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4,
+ 0x19, 0xdb, 0x06, 0xc1}},
+ {D_STR_W_LEN (""),
+ {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
+ 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
+ 0x78, 0x52, 0xb8, 0x55}},
+ {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
+ {0x2f, 0xad, 0x7a, 0xff, 0x7d, 0xfe, 0xcd, 0x78, 0xe4, 0xa6, 0xf3, 0x85,
+ 0x97, 0x9d, 0xdc, 0x39,
+ 0x55, 0x24, 0x35, 0x4a, 0x00, 0x6f, 0x42, 0x72, 0x41, 0xc1, 0x52, 0xa7,
+ 0x01, 0x0b, 0x2c, 0x41}},
+ {D_STR_W_LEN ("Simple string."),
+ {0x01, 0x73, 0x17, 0xc4, 0x0a, 0x9a, 0x0e, 0x81, 0xb3, 0xa4, 0xb1, 0x8e,
+ 0xe9, 0xd6, 0xc2, 0xdf,
+ 0xfa, 0x7d, 0x53, 0x4e, 0xa1, 0xda, 0xb2, 0x5a, 0x75, 0xbb, 0x2c, 0x30,
+ 0x2f, 0x5f, 0x7a, 0xf4}},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
+ {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44,
+ 0x7c, 0x66, 0xc9, 0x52,
+ 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2,
+ 0xda, 0xf1, 0x8b, 0x73}},
+ {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
+ {0xce, 0x7d, 0xde, 0xb6, 0x1f, 0x7c, 0x1d, 0x83, 0x7c, 0x60, 0xd8, 0x36,
+ 0x73, 0x82, 0xac, 0x92,
+ 0xca, 0x37, 0xfd, 0x72, 0x8b, 0x0c, 0xd1, 0x6c, 0x55, 0xd5, 0x88, 0x98,
+ 0x24, 0xfa, 0x16, 0xf2}},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"
+ "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
+ {0x27, 0xd1, 0xe8, 0xbc, 0x6a, 0x79, 0x16, 0x83, 0x61, 0x73, 0xa9, 0xa8,
+ 0x9b, 0xaf, 0xaf, 0xcf,
+ 0x47, 0x4d, 0x09, 0xef, 0x6d, 0x50, 0x35, 0x12, 0x25, 0x72, 0xd8, 0x68,
+ 0xdc, 0x1f, 0xd2, 0xf4}},
+};
+
+static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
+
+struct bin_with_len
+{
+ const uint8_t bin[512];
+ const size_t len;
+};
+
+struct data_unit2
+{
+ const struct bin_with_len bin_l;
+ const uint8_t digest[SHA256_DIGEST_SIZE];
+};
+
+/* Size must be less than 512 bytes! */
+static const struct data_unit2 data_units2[] = {
+ { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
+ {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44,
+ 0x7c, 0x66, 0xc9, 0x52,
+ 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2,
+ 0xda, 0xf1, 0x8b, 0x73}},
+ { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65}, 72 },/* 'A' x 72 times */
+ {0x6a, 0x6d, 0x69, 0x1a, 0xc9, 0xba, 0x70, 0x95, 0x50, 0x46, 0x75, 0x7c,
+ 0xd6, 0x85, 0xb6, 0x25,
+ 0x77, 0x73, 0xff, 0x3a, 0xd9, 0x3f, 0x43, 0xd4, 0xd4, 0x81, 0x2c, 0x5b,
+ 0x10, 0x6f, 0x4b, 0x5b}},
+ { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73}, 55}, /* 19..73 sequence */
+ {0x06, 0xe4, 0xb3, 0x9e, 0xf1, 0xfb, 0x6c, 0xcf, 0xd7, 0x3f, 0x50, 0x9e,
+ 0xf4, 0x16, 0x17, 0xd4,
+ 0x63, 0x7c, 0x39, 0x1e, 0xa8, 0x0f, 0xa9, 0x88, 0x03, 0x44, 0x98, 0x0e,
+ 0x95, 0x81, 0xf0, 0x2a}},
+ { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
+ {0x4a, 0xd3, 0xc6, 0x87, 0x1f, 0xd1, 0xc5, 0xe2, 0x3e, 0x52, 0xdc, 0x22,
+ 0xd1, 0x10, 0xd2, 0x05,
+ 0x15, 0x23, 0xcd, 0x15, 0xac, 0x24, 0x88, 0x26, 0x02, 0x00, 0x70, 0x78,
+ 0x9f, 0x17, 0xf8, 0xd9}},
+ { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92}, 55}, /* 38..92 sequence */
+ {0xe6, 0x03, 0x0f, 0xc9, 0x0d, 0xca, 0x0c, 0x26, 0x41, 0xcf, 0x43, 0x27,
+ 0xec, 0xd6, 0x28, 0x2a,
+ 0x98, 0x24, 0x55, 0xd3, 0x5a, 0xed, 0x8b, 0x32, 0x19, 0x78, 0xeb, 0x83,
+ 0x1d, 0x19, 0x92, 0x79}},
+ { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72},
+ 72},/* 1..72 sequence */
+ {0x87, 0xa2, 0xfa, 0x2e, 0xec, 0x53, 0x05, 0x3c, 0xb1, 0xee, 0x07, 0xd7,
+ 0x59, 0x70, 0xf6, 0x50,
+ 0xcd, 0x9d, 0xc5, 0x8b, 0xdc, 0xb8, 0x65, 0x30, 0x4f, 0x70, 0x82, 0x9e,
+ 0xbd, 0xe2, 0x7d, 0xac}},
+ { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160,
+ 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180,
+ 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 199, 200,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220,
+ 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 237, 238, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255}, 256}, /* 0..255 sequence */
+ {0x40, 0xaf, 0xf2, 0xe9, 0xd2, 0xd8, 0x92, 0x2e, 0x47, 0xaf, 0xd4, 0x64,
+ 0x8e, 0x69, 0x67, 0x49,
+ 0x71, 0x58, 0x78, 0x5f, 0xbd, 0x1d, 0xa8, 0x70, 0xe7, 0x11, 0x02, 0x66,
+ 0xbf, 0x94, 0x48, 0x80}},
+ { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
+ 185, 184, 183, 182, 181, 180,
+ 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
+ 165, 164, 163, 162, 161, 160,
+ 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
+ 145, 144, 143, 142, 141, 140,
+ 139}, 61}, /* 199..139 sequence */
+ {0x85, 0xf8, 0xa2, 0x83, 0xd6, 0x3c, 0x76, 0x8e, 0xea, 0x8f, 0x1c, 0x57,
+ 0x2d, 0x85, 0xb6, 0xff,
+ 0xd8, 0x33, 0x57, 0x62, 0x1d, 0x37, 0xae, 0x0e, 0xfc, 0x22, 0xd3, 0xd5,
+ 0x8f, 0x53, 0x21, 0xb7}},
+ { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
+ 241, 240, 239, 238, 237, 236,
+ 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222,
+ 221, 220, 219, 218, 217, 216,
+ 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202,
+ 201, 200, 199, 198, 197, 196,
+ 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182,
+ 181, 180, 179, 178, 177, 176,
+ 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162,
+ 161, 160, 159, 158, 157, 156,
+ 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142,
+ 141, 140, 139, 138, 137, 136,
+ 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122,
+ 121, 120, 119, 118, 117, 116,
+ 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
+ 101, 100, 99, 98, 97, 96, 95,
+ 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77,
+ 76, 75, 74, 73, 72, 71, 70,
+ 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52,
+ 51, 50, 49, 48, 47, 46, 45,
+ 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
+ 26, 25, 24, 23, 22, 21, 20,
+ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255}, /* 255..1 sequence */
+ {0x61, 0x86, 0x96, 0xab, 0x3e, 0xaa, 0x0e, 0x64, 0xb2, 0xf7, 0x2d, 0x75,
+ 0x47, 0x5a, 0x14, 0x97,
+ 0xa3, 0x3d, 0x59, 0xa4, 0x08, 0xd9, 0x9e, 0x73, 0xf2, 0x78, 0x00, 0x5b,
+ 0x4b, 0x55, 0xca, 0x43}},
+ { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
+ 235, 179, 166, 219, 60, 135,
+ 12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222, 179, 18, 77, 200, 67, 187,
+ 139, 166, 31, 3, 90, 125, 9,
+ 56, 37, 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28,
+ 219, 174, 50, 32, 154, 80, 238,
+ 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220, 173, 79, 20, 242,
+ 68, 64, 102, 208, 107, 196,
+ 48, 183, 50, 59, 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202,
+ 153, 2, 185, 114, 157, 73,
+ 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191, 103,
+ 214, 191, 20, 214, 126, 45,
+ 220, 142, 102, 131, 239, 87, 73, 97, 255, 105, 143, 97, 205, 209, 30,
+ 157, 156, 22, 114, 114, 230,
+ 29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51,
+ 116, 158, 12, 244, 213,
+ 212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244, 204, 207, 211, 144,
+ 45, 72, 211, 143, 117, 230,
+ 217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212,
+ 97, 141, 190, 123, 5, 21, 7,
+ 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62, 105, 21,
+ 248, 70, 106, 4, 150, 115,
+ 14, 217, 22, 47, 103, 104, 212, 247, 74, 74, 208, 87, 104}, 255}, /* pseudo-random data */
+ {0x08, 0x7f, 0x86, 0xac, 0xe2, 0x2e, 0x28, 0x56, 0x74, 0x53, 0x4f, 0xc0,
+ 0xfb, 0xb8, 0x79, 0x57,
+ 0xc5, 0xc8, 0xd1, 0xb7, 0x47, 0xb7, 0xd9, 0xea, 0x97, 0xa8, 0x67, 0xe9,
+ 0x26, 0x93, 0xee, 0xa3}}
+};
+
+static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
+
+
+/*
+ * Helper functions
+ */
+
+/**
+ * Print bin as hex
+ *
+ * @param bin binary data
+ * @param len number of bytes in bin
+ * @param hex pointer to len*2+1 bytes buffer
+ */
+static void
+bin2hex (const uint8_t *bin,
+ size_t len,
+ char *hex)
+{
+ while (len-- > 0)
+ {
+ unsigned int b1, b2;
+ b1 = (*bin >> 4) & 0xf;
+ *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
+ b2 = *bin++ & 0xf;
+ *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
+ }
+ *hex = 0;
+}
+
+
+static int
+check_result (const char *test_name,
+ unsigned int check_num,
+ const uint8_t calculated[SHA256_DIGEST_SIZE],
+ const uint8_t expected[SHA256_DIGEST_SIZE])
+{
+ int failed = memcmp (calculated, expected, SHA256_DIGEST_SIZE);
+ check_num++; /* Print 1-based numbers */
+ if (failed)
+ {
+ char calc_str[SHA256_DIGEST_STRING_SIZE];
+ char expc_str[SHA256_DIGEST_STRING_SIZE];
+ bin2hex (calculated, SHA256_DIGEST_SIZE, calc_str);
+ bin2hex (expected, SHA256_DIGEST_SIZE, expc_str);
+ fprintf (stderr,
+ "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
+ test_name, check_num, calc_str, expc_str);
+ fflush (stderr);
+ }
+ else if (verbose)
+ {
+ char calc_str[SHA256_DIGEST_STRING_SIZE];
+ bin2hex (calculated, SHA256_DIGEST_SIZE, calc_str);
+ printf (
+ "PASSED: %s check %u: calculated digest %s match expected digest.\n",
+ test_name, check_num, calc_str);
+ fflush (stdout);
+ }
+ return failed ? 1 : 0;
+}
+
+
+/*
+ * Tests
+ */
+
+/* Calculated SHA-256 as one pass for whole data */
+static int
+test1_str (void)
+{
+ int num_failed = 0;
+ unsigned int i;
+
+ for (i = 0; i < units1_num; i++)
+ {
+ struct sha256_ctx ctx;
+ uint8_t digest[SHA256_DIGEST_SIZE];
+
+ MHD_SHA256_init (&ctx);
+ MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str,
+ data_units1[i].str_l.len);
+ sha256_finish (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units1[i].digest);
+ }
+ return num_failed;
+}
+
+
+static int
+test1_bin (void)
+{
+ int num_failed = 0;
+ unsigned int i;
+
+ for (i = 0; i < units2_num; i++)
+ {
+ struct sha256_ctx ctx;
+ uint8_t digest[SHA256_DIGEST_SIZE];
+
+ MHD_SHA256_init (&ctx);
+ MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin,
+ data_units2[i].bin_l.len);
+ sha256_finish (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units2[i].digest);
+ }
+ return num_failed;
+}
+
+
+/* Calculated SHA-256 as two iterations for whole data */
+static int
+test2_str (void)
+{
+ int num_failed = 0;
+ unsigned int i;
+
+ for (i = 0; i < units1_num; i++)
+ {
+ struct sha256_ctx ctx;
+ uint8_t digest[SHA256_DIGEST_SIZE];
+ size_t part_s = data_units1[i].str_l.len / 4;
+
+ MHD_SHA256_init (&ctx);
+ MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str, part_s);
+ MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str + part_s,
+ data_units1[i].str_l.len - part_s);
+ sha256_finish (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units1[i].digest);
+ }
+ return num_failed;
+}
+
+
+static int
+test2_bin (void)
+{
+ int num_failed = 0;
+ unsigned int i;
+
+ for (i = 0; i < units2_num; i++)
+ {
+ struct sha256_ctx ctx;
+ uint8_t digest[SHA256_DIGEST_SIZE];
+ size_t part_s = data_units2[i].bin_l.len * 2 / 3;
+
+ MHD_SHA256_init (&ctx);
+ MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin, part_s);
+ MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin + part_s,
+ data_units2[i].bin_l.len - part_s);
+ sha256_finish (&ctx, digest);
+ num_failed += check_result (__FUNCTION__, i, digest,
+ data_units2[i].digest);
+ }
+ return num_failed;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int num_failed = 0;
+ (void) has_in_name; /* Mute compiler warning. */
+ if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
+ verbose = 1;
+
+ num_failed += test1_str ();
+ num_failed += test1_bin ();
+
+ num_failed += test2_str ();
+ num_failed += test2_bin ();
+
+ return num_failed ? 1 : 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_shutdown_select.c
^
|
@@ -50,7 +50,7 @@
#if defined(MHD_WINSOCK_SOCKETS)
#include <winsock2.h>
#include <windows.h>
-#define sock_errno (WSAGetLastError())
+#define sock_errno (WSAGetLastError ())
#elif defined(MHD_POSIX_SOCKETS)
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -83,7 +83,7 @@
#define SOMAXCONN 511
#endif /* ! SOMAXCONN */
-#if !defined(SHUT_RDWR) && defined(SD_BOTH)
+#if ! defined(SHUT_RDWR) && defined(SD_BOTH)
#define SHUT_RDWR SD_BOTH
#endif
@@ -91,33 +91,34 @@
static bool
-has_in_name(const char *prog_name, const char *marker)
+has_in_name (const char *prog_name, const char *marker)
{
size_t name_pos;
size_t pos;
- if (!prog_name || !marker)
+ if (! prog_name || ! marker)
return 0;
pos = 0;
name_pos = 0;
while (prog_name[pos])
- {
- if ('/' == prog_name[pos])
- name_pos = pos + 1;
-#ifdef _WIN32
- else if ('\\' == prog_name[pos])
- name_pos = pos + 1;
-#endif /* _WIN32 */
- pos++;
- }
+ {
+ if ('/' == prog_name[pos])
+ name_pos = pos + 1;
+#if defined(_WIN32) || defined(__CYGWIN__)
+ else if ('\\' == prog_name[pos])
+ name_pos = pos + 1;
+#endif /* _WIN32 || __CYGWIN__ */
+ pos++;
+ }
if (name_pos == pos)
- return !0;
- return strstr(prog_name + name_pos, marker) != NULL;
+ return true;
+ return strstr (prog_name + name_pos, marker) != NULL;
}
+
static MHD_socket
-start_socket_listen(int domain)
+start_socket_listen (int domain)
{
/* Create sockets similarly to daemon.c */
MHD_socket fd;
@@ -142,23 +143,23 @@
cloexec_set = 0;
#endif /* !SOCK_CLOEXEC */
if ( (MHD_INVALID_SOCKET == fd) && (cloexec_set) )
- {
- fd = socket (domain, SOCK_STREAM, 0);
- cloexec_set = 0;
- }
+ {
+ fd = socket (domain, SOCK_STREAM, 0);
+ cloexec_set = 0;
+ }
if (MHD_INVALID_SOCKET == fd)
- {
- fprintf (stderr, "Can't create socket: %u\n",
- (unsigned)sock_errno);
- return MHD_INVALID_SOCKET;
- }
+ {
+ fprintf (stderr, "Can't create socket: %u\n",
+ (unsigned) sock_errno);
+ return MHD_INVALID_SOCKET;
+ }
- if (!cloexec_set)
- {
+ if (! cloexec_set)
+ {
#ifdef MHD_WINSOCK_SOCKETS
- if (!SetHandleInformation ((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
+ if (! SetHandleInformation ((HANDLE) fd, HANDLE_FLAG_INHERIT, 0))
fprintf (stderr, "Failed to make socket non-inheritable: %u\n",
- (unsigned int)GetLastError ());
+ (unsigned int) GetLastError ());
#else /* MHD_POSIX_SOCKETS */
flags = fcntl (fd, F_GETFD);
if ( ( (-1 == flags) ||
@@ -167,84 +168,84 @@
fprintf (stderr, "Failed to make socket non-inheritable: %s\n",
MHD_socket_last_strerr_ ());
#endif /* MHD_POSIX_SOCKETS */
- }
+ }
memset (&sock_addr, 0, sizeof (struct sockaddr_in));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons (0);
-#if HAVE_SOCKADDR_IN_SIN_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
sock_addr.sin_len = sizeof (struct sockaddr_in);
#endif
addrlen = sizeof (struct sockaddr_in);
if (bind (fd, (const struct sockaddr*) &sock_addr, addrlen) < 0)
- {
- fprintf (stderr, "Failed to bind socket: %u\n",
- (unsigned)sock_errno);
- MHD_socket_close_chk_ (fd);
- return MHD_INVALID_SOCKET;
- }
+ {
+ fprintf (stderr, "Failed to bind socket: %u\n",
+ (unsigned) sock_errno);
+ MHD_socket_close_chk_ (fd);
+ return MHD_INVALID_SOCKET;
+ }
#ifdef MHD_WINSOCK_SOCKETS
if (0 != ioctlsocket (fd, FIONBIO, &flags))
- {
- fprintf (stderr, "Failed to make socket non-blocking: %u\n",
- (unsigned)sock_errno);
- MHD_socket_close_chk_ (fd);
- return MHD_INVALID_SOCKET;
- }
+ {
+ fprintf (stderr, "Failed to make socket non-blocking: %u\n",
+ (unsigned) sock_errno);
+ MHD_socket_close_chk_ (fd);
+ return MHD_INVALID_SOCKET;
+ }
#else /* MHD_POSIX_SOCKETS */
flags = fcntl (fd, F_GETFL);
if ( ( (-1 == flags) ||
( (flags != (flags | O_NONBLOCK)) &&
(0 != fcntl (fd, F_SETFL, flags | O_NONBLOCK)) ) ) )
- {
- fprintf (stderr, "Failed to make socket non-blocking: %s\n",
- MHD_socket_last_strerr_ ());
- MHD_socket_close_chk_ (fd);
- return MHD_INVALID_SOCKET;
- }
+ {
+ fprintf (stderr, "Failed to make socket non-blocking: %s\n",
+ MHD_socket_last_strerr_ ());
+ MHD_socket_close_chk_ (fd);
+ return MHD_INVALID_SOCKET;
+ }
#endif /* MHD_POSIX_SOCKETS */
- if (listen(fd, SOMAXCONN) < 0)
- {
- fprintf (stderr, "Failed to listen on socket: %u\n",
- (unsigned)sock_errno);
- MHD_socket_close_chk_ (fd);
- return MHD_INVALID_SOCKET;
- }
+ if (listen (fd, SOMAXCONN) < 0)
+ {
+ fprintf (stderr, "Failed to listen on socket: %u\n",
+ (unsigned) sock_errno);
+ MHD_socket_close_chk_ (fd);
+ return MHD_INVALID_SOCKET;
+ }
return fd;
}
MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
-select_thread(void* data)
+select_thread (void*data)
{
/* use select() like in daemon.c */
- MHD_socket listen_sock = *((MHD_socket*)data);
+ MHD_socket listen_sock = *((MHD_socket*) data);
fd_set rs, ws;
struct timeval timeout;
- FD_ZERO(&rs);
- FD_ZERO(&ws);
- FD_SET(listen_sock, &rs);
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_SET (listen_sock, &rs);
timeout.tv_usec = 0;
timeout.tv_sec = 7;
- check_err = (0 > MHD_SYS_select_(listen_sock + 1, &rs, &ws, NULL, &timeout));
+ check_err = (0 > MHD_SYS_select_ (listen_sock + 1, &rs, &ws, NULL, &timeout));
- return (MHD_THRD_RTRN_TYPE_)0;
+ return (MHD_THRD_RTRN_TYPE_) 0;
}
#ifdef HAVE_POLL
MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
-poll_thread(void* data)
+poll_thread (void*data)
{
/* use poll() like in daemon.c */
struct pollfd p[1];
- MHD_socket listen_sock = *((MHD_socket*)data);
+ MHD_socket listen_sock = *((MHD_socket*) data);
p[0].fd = listen_sock;
p[0].events = POLLIN;
@@ -252,22 +253,24 @@
check_err = (0 > MHD_sys_poll_ (p, 1, 7000));
- return (MHD_THRD_RTRN_TYPE_)0;
+ return (MHD_THRD_RTRN_TYPE_) 0;
}
+
+
#endif /* HAVE_POLL */
static void
-local_sleep(unsigned seconds)
+local_sleep (unsigned seconds)
{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- Sleep(seconds * 1000);
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ Sleep (seconds * 1000);
#else
unsigned seconds_left = seconds;
do
- {
- seconds_left = sleep(seconds_left);
- } while (seconds_left > 0);
+ {
+ seconds_left = sleep (seconds_left);
+ } while (seconds_left > 0);
#endif
}
@@ -278,106 +281,110 @@
int i;
time_t start_t, end_t;
int result = 0;
- MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *test_func)(void* data);
+ MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ * test_func)(void*data);
#ifdef MHD_WINSOCK_SOCKETS
WORD ver_req;
WSADATA wsa_data;
int err;
#endif /* MHD_WINSOCK_SOCKETS */
bool test_poll;
+ bool must_ignore;
+ (void) argc; /* Unused. Silent compiler warning. */
- test_poll = has_in_name(argv[0], "_poll");
- if (!test_poll)
+ test_poll = has_in_name (argv[0], "_poll");
+ must_ignore = has_in_name (argv[0], "_ignore");
+ if (! test_poll)
test_func = &select_thread;
else
- {
+ {
#ifndef HAVE_POLL
- return 77;
+ return 77;
#else /* ! HAVE_POLL */
- test_func = &poll_thread;
+ test_func = &poll_thread;
#endif /* ! HAVE_POLL */
- }
+ }
#ifdef MHD_WINSOCK_SOCKETS
- ver_req = MAKEWORD(2, 2);
+ ver_req = MAKEWORD (2, 2);
- err = WSAStartup(ver_req, &wsa_data);
- if (err != 0 || MAKEWORD(2, 2) != wsa_data.wVersion)
- {
- printf("WSAStartup() failed\n");
- WSACleanup();
- return 99;
- }
+ err = WSAStartup (ver_req, &wsa_data);
+ if ((err != 0) || (MAKEWORD (2, 2) != wsa_data.wVersion))
+ {
+ printf ("WSAStartup() failed\n");
+ WSACleanup ();
+ return 99;
+ }
#endif /* MHD_WINSOCK_SOCKETS */
/* try several times to ensure that accidental incoming connection
* didn't interfere with test results
*/
for (i = 0; i < 5 && result == 0; i++)
- {
- MHD_thread_handle_ sel_thrd;
- /* fprintf(stdout, "Creating, binding and listening socket...\n"); */
- MHD_socket listen_socket = start_socket_listen (AF_INET);
- if (MHD_INVALID_SOCKET == listen_socket)
- return 99;
+ {
+ MHD_thread_handle_ sel_thrd;
+ /* fprintf(stdout, "Creating, binding and listening socket...\n"); */
+ MHD_socket listen_socket = start_socket_listen (AF_INET);
+ if (MHD_INVALID_SOCKET == listen_socket)
+ return 99;
- check_err = !0;
- /* fprintf (stdout, "Starting select() thread...\n"); */
+ check_err = true;
+ /* fprintf (stdout, "Starting select() thread...\n"); */
#if defined(MHD_USE_POSIX_THREADS)
- if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket))
- {
- MHD_socket_close_chk_ (listen_socket);
- fprintf (stderr, "Can't start thread\n");
- return 99;
- }
+ if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket))
+ {
+ MHD_socket_close_chk_ (listen_socket);
+ fprintf (stderr, "Can't start thread\n");
+ return 99;
+ }
#elif defined(MHD_USE_W32_THREADS)
- sel_thrd = (HANDLE)_beginthreadex (NULL, 0, test_func, &listen_socket, 0, NULL);
- if (0 == (sel_thrd))
- {
- MHD_socket_close_chk_ (listen_socket);
- fprintf (stderr, "Can't start select() thread\n");
- return 99;
- }
+ sel_thrd = (HANDLE) _beginthreadex (NULL, 0, test_func, &listen_socket, 0,
+ NULL);
+ if (0 == (sel_thrd))
+ {
+ MHD_socket_close_chk_ (listen_socket);
+ fprintf (stderr, "Can't start select() thread\n");
+ return 99;
+ }
#else
#error No threading lib available
#endif
- /* fprintf (stdout, "Waiting...\n"); */
- local_sleep(1); /* make sure that select() is started */
+ /* fprintf (stdout, "Waiting...\n"); */
+ local_sleep (1); /* make sure that select() is started */
- /* fprintf (stdout, "Shutting down socket...\n"); */
- start_t = time (NULL);
- shutdown (listen_socket, SHUT_RDWR);
-
- /* fprintf (stdout, "Waiting for thread to finish...\n"); */
- if (!MHD_join_thread_(sel_thrd))
- {
- MHD_socket_close_chk_(listen_socket);
- fprintf (stderr, "Can't join select() thread\n");
- return 99;
- }
- if (check_err)
- {
- MHD_socket_close_chk_(listen_socket);
- fprintf (stderr, "Error in waiting thread\n");
- return 99;
- }
- end_t = time (NULL);
- /* fprintf (stdout, "Thread finished.\n"); */
- MHD_socket_close_chk_(listen_socket);
-
- if (start_t == (time_t)-1 || end_t == (time_t)-1)
- {
- MHD_socket_close_chk_(listen_socket);
- fprintf (stderr, "Can't get current time\n");
- return 99;
- }
- if (end_t - start_t > 3)
- result++;
+ /* fprintf (stdout, "Shutting down socket...\n"); */
+ start_t = time (NULL);
+ shutdown (listen_socket, SHUT_RDWR);
+
+ /* fprintf (stdout, "Waiting for thread to finish...\n"); */
+ if (! MHD_join_thread_ (sel_thrd))
+ {
+ MHD_socket_close_chk_ (listen_socket);
+ fprintf (stderr, "Can't join select() thread\n");
+ return 99;
+ }
+ if (check_err)
+ {
+ MHD_socket_close_chk_ (listen_socket);
+ fprintf (stderr, "Error in waiting thread\n");
+ return 99;
+ }
+ end_t = time (NULL);
+ /* fprintf (stdout, "Thread finished.\n"); */
+ MHD_socket_close_chk_ (listen_socket);
+
+ if ((start_t == (time_t) -1) || (end_t == (time_t) -1) )
+ {
+ MHD_socket_close_chk_ (listen_socket);
+ fprintf (stderr, "Can't get current time\n");
+ return 99;
}
+ if (end_t - start_t > 3)
+ result++;
+ }
#ifdef MHD_WINSOCK_SOCKETS
- WSACleanup();
+ WSACleanup ();
#endif /* MHD_WINSOCK_SOCKETS */
- return result;
+ return must_ignore ? (! result) : (result);
}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_start_stop.c
^
|
@@ -0,0 +1,155 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2011 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_start_stop.c
+ * @brief test for #1901 (start+stop)
+ * @author Christian Grothoff
+ */
+#include "mhd_options.h"
+#include "platform.h"
+#include <microhttpd.h>
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ (void) cls; (void) connection; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
+
+ return MHD_NO;
+}
+
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+static int
+testInternalGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ 0, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+
+static int
+testMultithreadedGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ 0, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ return 2;
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+
+static int
+testMultithreadedPoolGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ 0, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 4;
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+
+#endif
+
+
+static int
+testExternalGet ()
+{
+ struct MHD_Daemon *d;
+
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+ 0, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_END);
+ if (NULL == d)
+ return 8;
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ unsigned int errorCount = 0;
+ (void) argc;
+ (void) argv; /* Unused. Silence compiler warning. */
+
+#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ errorCount += testInternalGet (0);
+ errorCount += testMultithreadedGet (0);
+ errorCount += testMultithreadedPoolGet (0);
+#endif
+ errorCount += testExternalGet ();
+#if defined (MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ errorCount += testInternalGet (MHD_USE_POLL);
+ errorCount += testMultithreadedGet (MHD_USE_POLL);
+ errorCount += testMultithreadedPoolGet (MHD_USE_POLL);
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ {
+ errorCount += testInternalGet (MHD_USE_EPOLL);
+ errorCount += testMultithreadedPoolGet (MHD_USE_EPOLL);
+ }
+#endif
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ errorCount);
+ return errorCount != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_str.c
^
|
@@ -46,235 +46,242 @@
* Functions must not depend of current current locale,
* so result must be the same in any locale.
*/
-static const char * const locale_names[] = {
- "C",
- "", /* System default locale */
-#if defined(_WIN32) && !defined(__CYGWIN__)
- ".OCP", /* W32 system default OEM code page */
- ".ACP", /* W32 system default ANSI code page */
- ".65001", /* UTF-8 */
- ".437",
- ".850",
- ".857",
- ".866",
- ".1250",
- ".1251",
- ".1252",
- ".1254",
- ".20866", /* number for KOI8-R */
- ".28591", /* number for ISO-8859-1 */
- ".28595", /* number for ISO-8859-5 */
- ".28599", /* number for ISO-8859-9 */
- ".28605", /* number for ISO-8859-15 */
- "en",
- "english",
- "en-US",
- "English-US",
- "en-US.437",
- "English_United States.437",
- "en-US.1252",
- "English_United States.1252",
- "English_United States.28591",
- "English_United States.65001",
- "fra",
- "french",
- "fr-FR",
- "French_France",
- "fr-FR.850",
- "french_france.850",
- "fr-FR.1252",
- "French_france.1252",
- "French_france.28605",
- "French_France.65001",
- "de",
- "de-DE",
- "de-DE.850",
- "German_Germany.850",
- "German_Germany.1250",
- "de-DE.1252",
- "German_Germany.1252",
- "German_Germany.28605",
- "German_Germany.65001",
- "tr",
- "trk",
- "turkish",
- "tr-TR",
- "tr-TR.1254",
- "Turkish_Turkey.1254",
- "tr-TR.857",
- "Turkish_Turkey.857",
- "Turkish_Turkey.28599",
- "Turkish_Turkey.65001",
- "ru",
- "ru-RU",
- "Russian",
- "ru-RU.866",
- "Russian_Russia.866",
- "ru-RU.1251",
- "Russian_Russia.1251",
- "Russian_Russia.20866",
- "Russian_Russia.28595",
- "Russian_Russia.65001",
- "zh-Hans",
- "zh-Hans.936",
- "chinese-simplified"
+static const char *const locale_names[] = {
+ "C",
+ "", /* System default locale */
+#if defined(_WIN32) && ! defined(__CYGWIN__)
+ ".OCP", /* W32 system default OEM code page */
+ ".ACP", /* W32 system default ANSI code page */
+ ".65001", /* UTF-8 */
+ ".437",
+ ".850",
+ ".857",
+ ".866",
+ ".1250",
+ ".1251",
+ ".1252",
+ ".1254",
+ ".20866", /* number for KOI8-R */
+ ".28591", /* number for ISO-8859-1 */
+ ".28595", /* number for ISO-8859-5 */
+ ".28599", /* number for ISO-8859-9 */
+ ".28605", /* number for ISO-8859-15 */
+ "en",
+ "english",
+ "en-US",
+ "English-US",
+ "en-US.437",
+ "English_United States.437",
+ "en-US.1252",
+ "English_United States.1252",
+ "English_United States.28591",
+ "English_United States.65001",
+ "fra",
+ "french",
+ "fr-FR",
+ "French_France",
+ "fr-FR.850",
+ "french_france.850",
+ "fr-FR.1252",
+ "French_france.1252",
+ "French_france.28605",
+ "French_France.65001",
+ "de",
+ "de-DE",
+ "de-DE.850",
+ "German_Germany.850",
+ "German_Germany.1250",
+ "de-DE.1252",
+ "German_Germany.1252",
+ "German_Germany.28605",
+ "German_Germany.65001",
+ "tr",
+ "trk",
+ "turkish",
+ "tr-TR",
+ "tr-TR.1254",
+ "Turkish_Turkey.1254",
+ "tr-TR.857",
+ "Turkish_Turkey.857",
+ "Turkish_Turkey.28599",
+ "Turkish_Turkey.65001",
+ "ru",
+ "ru-RU",
+ "Russian",
+ "ru-RU.866",
+ "Russian_Russia.866",
+ "ru-RU.1251",
+ "Russian_Russia.1251",
+ "Russian_Russia.20866",
+ "Russian_Russia.28595",
+ "Russian_Russia.65001",
+ "zh-Hans",
+ "zh-Hans.936",
+ "chinese-simplified"
#else /* ! _WIN32 || __CYGWIN__ */
- "C.UTF-8",
- "POSIX",
- "en",
- "en_US",
- "en_US.ISO-8859-1",
- "en_US.ISO_8859-1",
- "en_US.ISO8859-1",
- "en_US.iso88591",
- "en_US.ISO-8859-15",
- "en_US.DIS_8859-15",
- "en_US.ISO8859-15",
- "en_US.iso885915",
- "en_US.1252",
- "en_US.CP1252",
- "en_US.UTF-8",
- "en_US.utf8",
- "fr",
- "fr_FR",
- "fr_FR.850",
- "fr_FR.IBM850",
- "fr_FR.1252",
- "fr_FR.CP1252",
- "fr_FR.ISO-8859-1",
- "fr_FR.ISO_8859-1",
- "fr_FR.ISO8859-1",
- "fr_FR.iso88591",
- "fr_FR.ISO-8859-15",
- "fr_FR.DIS_8859-15",
- "fr_FR.ISO8859-15",
- "fr_FR.iso8859-15",
- "fr_FR.UTF-8",
- "fr_FR.utf8",
- "de",
- "de_DE",
- "de_DE.850",
- "de_DE.IBM850",
- "de_DE.1250",
- "de_DE.CP1250",
- "de_DE.1252",
- "de_DE.CP1252",
- "de_DE.ISO-8859-1",
- "de_DE.ISO_8859-1",
- "de_DE.ISO8859-1",
- "de_DE.iso88591",
- "de_DE.ISO-8859-15",
- "de_DE.DIS_8859-15",
- "de_DE.ISO8859-15",
- "de_DE.iso885915",
- "de_DE.UTF-8",
- "de_DE.utf8",
- "tr",
- "tr_TR",
- "tr_TR.1254",
- "tr_TR.CP1254",
- "tr_TR.857",
- "tr_TR.IBM857",
- "tr_TR.ISO-8859-9",
- "tr_TR.ISO8859-9",
- "tr_TR.iso88599",
- "tr_TR.UTF-8",
- "tr_TR.utf8",
- "ru",
- "ru_RU",
- "ru_RU.1251",
- "ru_RU.CP1251",
- "ru_RU.866",
- "ru_RU.IBM866",
- "ru_RU.KOI8-R",
- "ru_RU.koi8-r",
- "ru_RU.KOI8-RU",
- "ru_RU.ISO-8859-5",
- "ru_RU.ISO_8859-5",
- "ru_RU.ISO8859-5",
- "ru_RU.iso88595",
- "ru_RU.UTF-8",
- "zh_CN",
- "zh_CN.GB2312",
- "zh_CN.UTF-8",
+ "C.UTF-8",
+ "POSIX",
+ "en",
+ "en_US",
+ "en_US.ISO-8859-1",
+ "en_US.ISO_8859-1",
+ "en_US.ISO8859-1",
+ "en_US.iso88591",
+ "en_US.ISO-8859-15",
+ "en_US.DIS_8859-15",
+ "en_US.ISO8859-15",
+ "en_US.iso885915",
+ "en_US.1252",
+ "en_US.CP1252",
+ "en_US.UTF-8",
+ "en_US.utf8",
+ "fr",
+ "fr_FR",
+ "fr_FR.850",
+ "fr_FR.IBM850",
+ "fr_FR.1252",
+ "fr_FR.CP1252",
+ "fr_FR.ISO-8859-1",
+ "fr_FR.ISO_8859-1",
+ "fr_FR.ISO8859-1",
+ "fr_FR.iso88591",
+ "fr_FR.ISO-8859-15",
+ "fr_FR.DIS_8859-15",
+ "fr_FR.ISO8859-15",
+ "fr_FR.iso8859-15",
+ "fr_FR.UTF-8",
+ "fr_FR.utf8",
+ "de",
+ "de_DE",
+ "de_DE.850",
+ "de_DE.IBM850",
+ "de_DE.1250",
+ "de_DE.CP1250",
+ "de_DE.1252",
+ "de_DE.CP1252",
+ "de_DE.ISO-8859-1",
+ "de_DE.ISO_8859-1",
+ "de_DE.ISO8859-1",
+ "de_DE.iso88591",
+ "de_DE.ISO-8859-15",
+ "de_DE.DIS_8859-15",
+ "de_DE.ISO8859-15",
+ "de_DE.iso885915",
+ "de_DE.UTF-8",
+ "de_DE.utf8",
+ "tr",
+ "tr_TR",
+ "tr_TR.1254",
+ "tr_TR.CP1254",
+ "tr_TR.857",
+ "tr_TR.IBM857",
+ "tr_TR.ISO-8859-9",
+ "tr_TR.ISO8859-9",
+ "tr_TR.iso88599",
+ "tr_TR.UTF-8",
+ "tr_TR.utf8",
+ "ru",
+ "ru_RU",
+ "ru_RU.1251",
+ "ru_RU.CP1251",
+ "ru_RU.866",
+ "ru_RU.IBM866",
+ "ru_RU.KOI8-R",
+ "ru_RU.koi8-r",
+ "ru_RU.KOI8-RU",
+ "ru_RU.ISO-8859-5",
+ "ru_RU.ISO_8859-5",
+ "ru_RU.ISO8859-5",
+ "ru_RU.iso88595",
+ "ru_RU.UTF-8",
+ "zh_CN",
+ "zh_CN.GB2312",
+ "zh_CN.UTF-8",
#endif /* ! _WIN32 || __CYGWIN__ */
};
-static const unsigned int locale_name_count = sizeof(locale_names) / sizeof(locale_names[0]);
+static const unsigned int locale_name_count = sizeof(locale_names)
+ / sizeof(locale_names[0]);
/*
* Helper functions
*/
-int set_test_locale(unsigned int num)
+int
+set_test_locale (unsigned int num)
{
if (num >= locale_name_count)
return -1;
if (verbose > 2)
- printf("Setting locale \"%s\":", locale_names[num]);
- if (setlocale(LC_ALL, locale_names[num]))
- {
- if (verbose > 2)
- printf(" succeed.\n");
- return 1;
- }
- if (verbose > 2)
- printf(" failed.\n");
- return 0;
+ printf ("Setting locale \"%s\":", locale_names[num]);
+ if (setlocale (LC_ALL, locale_names[num]))
+ {
+ if (verbose > 2)
+ printf (" succeed.\n");
+ return 1;
+ }
+ if (verbose > 2)
+ printf (" failed.\n");
+ return 0;
}
-const char * get_current_locale_str(void)
+
+const char *
+get_current_locale_str (void)
{
- char const * loc_str = setlocale(LC_ALL, NULL);
+ char const *loc_str = setlocale (LC_ALL, NULL);
return loc_str ? loc_str : "unknown";
}
-static char tmp_bufs[4][4*1024]; /* should be enough for testing */
+
+static char tmp_bufs[4][4 * 1024]; /* should be enough for testing */
static size_t buf_idx = 0;
/* print non-printable chars as char codes */
-char * n_prnt(const char * str)
+char *
+n_prnt (const char *str)
{
- static char * buf; /* should be enough for testing */
+ static char *buf; /* should be enough for testing */
static const size_t buf_size = sizeof(tmp_bufs[0]);
- const unsigned char * p = (const unsigned char*)str;
+ const unsigned char *p = (const unsigned char*) str;
size_t w_pos = 0;
if (++buf_idx > 3)
buf_idx = 0;
buf = tmp_bufs[buf_idx];
- while(*p && w_pos + 1 < buf_size)
- {
- const unsigned char c = *p;
- if (c == '\\' || c == '"')
- {
- if (w_pos + 2 >= buf_size)
- break;
- buf[w_pos++] = '\\';
- buf[w_pos++] = c;
- }
- else if (c >= 0x20 && c <= 0x7E)
- buf[w_pos++] = c;
- else
- {
- if (w_pos + 4 >= buf_size)
- break;
- if (snprintf(buf + w_pos, buf_size - w_pos, "\\x%02hX", (short unsigned int)c) != 4)
- break;
- w_pos += 4;
- }
- p++;
+ while (*p && w_pos + 1 < buf_size)
+ {
+ const unsigned char c = *p;
+ if ((c == '\\') || (c == '"') )
+ {
+ if (w_pos + 2 >= buf_size)
+ break;
+ buf[w_pos++] = '\\';
+ buf[w_pos++] = c;
+ }
+ else if ((c >= 0x20) && (c <= 0x7E) )
+ buf[w_pos++] = c;
+ else
+ {
+ if (w_pos + 4 >= buf_size)
+ break;
+ if (snprintf (buf + w_pos, buf_size - w_pos, "\\x%02hX", (short unsigned
+ int) c) != 4)
+ break;
+ w_pos += 4;
}
+ p++;
+ }
if (*p)
- { /* not full string is printed */
+ { /* not full string is printed */
/* enough space for "..." ? */
- if (w_pos + 3 > buf_size)
- w_pos = buf_size - 4;
- buf[w_pos++] = '.';
- buf[w_pos++] = '.';
- buf[w_pos++] = '.';
- }
+ if (w_pos + 3 > buf_size)
+ w_pos = buf_size - 4;
+ buf[w_pos++] = '.';
+ buf[w_pos++] = '.';
+ buf[w_pos++] = '.';
+ }
buf[w_pos] = 0;
return buf;
}
@@ -282,7 +289,7 @@
struct str_with_len
{
- const char * const str;
+ const char *const str;
const size_t len;
};
@@ -299,118 +306,129 @@
};
static const struct two_eq_strs eq_strings[] = {
- {D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`.")},
- {D_STR_W_LEN("Simple string."), D_STR_W_LEN("Simple string.")},
- {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("SIMPLE STRING.")},
- {D_STR_W_LEN("simple string."), D_STR_W_LEN("simple string.")},
- {D_STR_W_LEN("simple string."), D_STR_W_LEN("Simple String.")},
- {D_STR_W_LEN("sImPlE StRiNg."), D_STR_W_LEN("SiMpLe sTrInG.")},
- {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("simple string.")},
- {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz")},
- {D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
- {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
- {D_STR_W_LEN("zyxwvutsrqponMLKJIHGFEDCBA"), D_STR_W_LEN("ZYXWVUTSRQPONmlkjihgfedcba")},
-
- {D_STR_W_LEN("Cha\x8cne pour le test."),
- D_STR_W_LEN("Cha\x8cne pour le test.")}, /* "Chaîne pour le test." in CP850 */
- {D_STR_W_LEN("cha\x8cne pOur Le TEst."),
- D_STR_W_LEN("Cha\x8cne poUr Le teST.")},
- {D_STR_W_LEN("Cha\xeene pour le test."),
- D_STR_W_LEN("Cha\xeene pour le test.")}, /* "Chaîne pour le test." in CP1252/ISO-8859-1/ISO-8859-15 */
- {D_STR_W_LEN("CHa\xeene POUR le test."),
- D_STR_W_LEN("Cha\xeeNe pour lE TEST.")},
- {D_STR_W_LEN("Cha\xc3\xaene pour le Test."),
- D_STR_W_LEN("Cha\xc3\xaene pour le Test.")}, /* "Chaîne pour le test." in UTF-8 */
- {D_STR_W_LEN("ChA\xc3\xaene pouR lE TesT."),
- D_STR_W_LEN("Cha\xc3\xaeNe Pour le teSt.")},
-
- {D_STR_W_LEN(".Beispiel Zeichenfolge"),
- D_STR_W_LEN(".Beispiel Zeichenfolge")},
- {D_STR_W_LEN(".bEisPiel ZEIchenfoLgE"),
- D_STR_W_LEN(".BEiSpiEl zeIcheNfolge")},
-
- {D_STR_W_LEN("Do\xa7rulama \x87izgi!"),
- D_STR_W_LEN("Do\xa7rulama \x87izgi!")}, /* "Doğrulama çizgi!" in CP857 */
- {D_STR_W_LEN("Do\xa7rulama \x87IzgI!"), /* Spelling intentionally incorrect here */
- D_STR_W_LEN("Do\xa7rulama \x87izgi!")}, /* Note: 'i' is not caseless equal to 'I' in Turkish */
- {D_STR_W_LEN("Do\xf0rulama \xe7izgi!"),
- D_STR_W_LEN("Do\xf0rulama \xe7izgi!")}, /* "Doğrulama çizgi!" in CP1254/ISO-8859-9 */
- {D_STR_W_LEN("Do\xf0rulamA \xe7Izgi!"),
- D_STR_W_LEN("do\xf0rulama \xe7izgi!")},
- {D_STR_W_LEN("Do\xc4\x9frulama \xc3\xa7izgi!"),
- D_STR_W_LEN("Do\xc4\x9frulama \xc3\xa7izgi!")}, /* "Doğrulama çizgi!" in UTF-8 */
- {D_STR_W_LEN("do\xc4\x9fruLAMA \xc3\xa7Izgi!"), /* Spelling intentionally incorrect here */
- D_STR_W_LEN("DO\xc4\x9frulama \xc3\xa7izgI!")}, /* Spelling intentionally incorrect here */
-
- {D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."),
- D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0.")}, /* "Тестовая Строка." in CP866 */
- {D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."),
- D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0.")}, /* "Тестовая Строка." in CP1251 */
- {D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."),
- D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1.")}, /* "Тестовая Строка." in KOI8-R */
- {D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."),
- D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0.")}, /* "Тестовая Строка." in ISO-8859-5 */
- {D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
- "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."),
- D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
- "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0.")}, /* "Тестовая Строка." in UTF-8 */
-
- {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
- "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
- "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
- "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
- "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
- "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
- "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
- "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
- D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
- "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
- "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
- "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
- "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
- "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
- "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
- "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")}, /* Full sequence without a-z */
- {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
- "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
- "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
- "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
- "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
- "\xfc\xfd\xfe\xff"),
- D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
- "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
- "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
- "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
- "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
- "\xfc\xfd\xfe\xff")}, /* Full sequence */
- {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
- "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
- "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
- "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
- "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
- "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
- "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
- "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
- D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ab"
- "cdefghijklmnopqrstuvwxyz[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
- "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
- "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
- "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
- "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
- "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
- "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")} /* Full with A/a match */
+ {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN (
+ "1234567890!@~%&$@#{}[]\\/!?`.")},
+ {D_STR_W_LEN ("Simple string."), D_STR_W_LEN ("Simple string.")},
+ {D_STR_W_LEN ("SIMPLE STRING."), D_STR_W_LEN ("SIMPLE STRING.")},
+ {D_STR_W_LEN ("simple string."), D_STR_W_LEN ("simple string.")},
+ {D_STR_W_LEN ("simple string."), D_STR_W_LEN ("Simple String.")},
+ {D_STR_W_LEN ("sImPlE StRiNg."), D_STR_W_LEN ("SiMpLe sTrInG.")},
+ {D_STR_W_LEN ("SIMPLE STRING."), D_STR_W_LEN ("simple string.")},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN (
+ "abcdefghijklmnopqrstuvwxyz")},
+ {D_STR_W_LEN ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), D_STR_W_LEN (
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN (
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
+ {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"), D_STR_W_LEN (
+ "ZYXWVUTSRQPONmlkjihgfedcba")},
+
+ {D_STR_W_LEN ("Cha\x8cne pour le test."),
+ D_STR_W_LEN ("Cha\x8cne pour le test.")}, /* "Chaîne pour le test." in CP850 */
+ {D_STR_W_LEN ("cha\x8cne pOur Le TEst."),
+ D_STR_W_LEN ("Cha\x8cne poUr Le teST.")},
+ {D_STR_W_LEN ("Cha\xeene pour le test."),
+ D_STR_W_LEN ("Cha\xeene pour le test.")}, /* "Chaîne pour le test." in CP1252/ISO-8859-1/ISO-8859-15 */
+ {D_STR_W_LEN ("CHa\xeene POUR le test."),
+ D_STR_W_LEN ("Cha\xeeNe pour lE TEST.")},
+ {D_STR_W_LEN ("Cha\xc3\xaene pour le Test."),
+ D_STR_W_LEN ("Cha\xc3\xaene pour le Test.")}, /* "Chaîne pour le test." in UTF-8 */
+ {D_STR_W_LEN ("ChA\xc3\xaene pouR lE TesT."),
+ D_STR_W_LEN ("Cha\xc3\xaeNe Pour le teSt.")},
+
+ {D_STR_W_LEN (".Beispiel Zeichenfolge"),
+ D_STR_W_LEN (".Beispiel Zeichenfolge")},
+ {D_STR_W_LEN (".bEisPiel ZEIchenfoLgE"),
+ D_STR_W_LEN (".BEiSpiEl zeIcheNfolge")},
+
+ {D_STR_W_LEN ("Do\xa7rulama \x87izgi!"),
+ D_STR_W_LEN ("Do\xa7rulama \x87izgi!")}, /* "Doğrulama çizgi!" in CP857 */
+ {D_STR_W_LEN ("Do\xa7rulama \x87IzgI!"), /* Spelling intentionally incorrect here */
+ D_STR_W_LEN ("Do\xa7rulama \x87izgi!")}, /* Note: 'i' is not caseless equal to 'I' in Turkish */
+ {D_STR_W_LEN ("Do\xf0rulama \xe7izgi!"),
+ D_STR_W_LEN ("Do\xf0rulama \xe7izgi!")}, /* "Doğrulama çizgi!" in CP1254/ISO-8859-9 */
+ {D_STR_W_LEN ("Do\xf0rulamA \xe7Izgi!"),
+ D_STR_W_LEN ("do\xf0rulama \xe7izgi!")},
+ {D_STR_W_LEN ("Do\xc4\x9frulama \xc3\xa7izgi!"),
+ D_STR_W_LEN ("Do\xc4\x9frulama \xc3\xa7izgi!")}, /* "Doğrulama çizgi!" in UTF-8 */
+ {D_STR_W_LEN ("do\xc4\x9fruLAMA \xc3\xa7Izgi!"), /* Spelling intentionally incorrect here */
+ D_STR_W_LEN ("DO\xc4\x9frulama \xc3\xa7izgI!")}, /* Spelling intentionally incorrect here */
+
+ {D_STR_W_LEN ("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."),
+ D_STR_W_LEN ("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0.")}, /* "Тестовая Строка." in CP866 */
+ {D_STR_W_LEN ("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."),
+ D_STR_W_LEN ("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0.")}, /* "Тестовая Строка." in CP1251 */
+ {D_STR_W_LEN ("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."),
+ D_STR_W_LEN ("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1.")}, /* "Тестовая Строка." in KOI8-R */
+ {D_STR_W_LEN ("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."),
+ D_STR_W_LEN ("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0.")}, /* "Тестовая Строка." in ISO-8859-5 */
+ {D_STR_W_LEN ("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
+ "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."),
+ D_STR_W_LEN ("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
+ "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0.")}, /* "Тестовая Строка." in UTF-8 */
+
+ {D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
+ "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
+ "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
+ "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
+ "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
+ D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
+ "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
+ "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
+ "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
+ "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")}, /* Full sequence without a-z */
+ {D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
+ "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
+ "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
+ "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
+ "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
+ "\xfc\xfd\xfe\xff"),
+ D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
+ "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
+ "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
+ "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
+ "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
+ "\xfc\xfd\xfe\xff")}, /* Full sequence */
+ {D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
+ "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
+ "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
+ "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
+ "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
+ "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
+ "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
+ "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
+ D_STR_W_LEN (
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ab"
+ "cdefghijklmnopqrstuvwxyz[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
+ "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
+ "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
+ "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
+ "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
+ "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
+ "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")} /* Full with A/a match */
};
struct two_neq_strs
@@ -421,376 +439,439 @@
};
static const struct two_neq_strs neq_strings[] = {
- {D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`"), 27},
- {D_STR_W_LEN(".1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`"), 0},
- {D_STR_W_LEN("Simple string."), D_STR_W_LEN("Simple ctring."), 7},
- {D_STR_W_LEN("simple string."), D_STR_W_LEN("simple string"), 13},
- {D_STR_W_LEN("simple strings"), D_STR_W_LEN("Simple String."), 13},
- {D_STR_W_LEN("sImPlE StRiNg."), D_STR_W_LEN("SYMpLe sTrInG."), 1},
- {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("simple string.2"), 14},
- {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz,"), D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz."), 26},
- {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz!"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ?"), 26},
- {D_STR_W_LEN("zyxwvutsrqponwMLKJIHGFEDCBA"), D_STR_W_LEN("ZYXWVUTSRQPON%mlkjihgfedcba"), 13},
-
- {D_STR_W_LEN("S\xbdur veulent plus d'\xbdufs."), /* "Sœur veulent plus d'œufs." in ISO-8859-15 */
- D_STR_W_LEN("S\xbcUR VEULENT PLUS D'\xbcUFS."), 1},/* "SŒUR VEULENT PLUS D'ŒUFS." in ISO-8859-15 */
- {D_STR_W_LEN("S\x9cur veulent plus d'\x9cufs."), /* "Sœur veulent plus d'œufs." in CP1252 */
- D_STR_W_LEN("S\x8cUR VEULENT PLUS D'\x8cUFS."), 1},/* "SŒUR VEULENT PLUS D'ŒUFS." in CP1252 */
- {D_STR_W_LEN("S\xc5\x93ur veulent plus d'\xc5\x93ufs."), /* "Sœur veulent plus d'œufs." in UTF-8 */
- D_STR_W_LEN("S\xc5\x92UR VEULENT PLUS D'\xc5\x92UFS."), 2},/* "SŒUR VEULENT PLUS D'ŒUFS." in UTF-8 */
-
- {D_STR_W_LEN("Um ein sch\x94nes M\x84" "dchen zu k\x81ssen."), /* "Um ein schönes Mädchen zu küssen." in CP850 */
- D_STR_W_LEN("UM EIN SCH\x99NES M\x8e" "DCHEN ZU K\x9aSSEN."), 10},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in CP850 */
- {D_STR_W_LEN("Um ein sch\xf6nes M\xe4" "dchen zu k\xfcssen."), /* "Um ein schönes Mädchen zu küssen." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
- D_STR_W_LEN("UM EIN SCH\xd6NES M\xc4" "DCHEN ZU K\xdcSSEN."), 10},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
- {D_STR_W_LEN("Um ein sch\xc3\xb6nes M\xc3\xa4" "dchen zu k\xc3\xbcssen."), /* "Um ein schönes Mädchen zu küssen." in UTF-8 */
- D_STR_W_LEN("UM EIN SCH\xc3\x96NES M\xc3\x84" "DCHEN ZU K\xc3\x9cSSEN."), 11},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in UTF-8 */
-
- {D_STR_W_LEN("\x98stanbul"), /* "İstanbul" in CP857 */
- D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in CP857 */
- {D_STR_W_LEN("\xddstanbul"), /* "İstanbul" in ISO-8859-9/CP1254 */
- D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in ISO-8859-9/CP1254 */
- {D_STR_W_LEN("\xc4\xb0stanbul"), /* "İstanbul" in UTF-8 */
- D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in UTF-8 */
- {D_STR_W_LEN("Diyarbak\x8dr"), /* "Diyarbakır" in CP857 */
- D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in CP857 */
- {D_STR_W_LEN("Diyarbak\xfdr"), /* "Diyarbakır" in ISO-8859-9/CP1254 */
- D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in ISO-8859-9/CP1254 */
- {D_STR_W_LEN("Diyarbak\xc4\xb1r"), /* "Diyarbakır" in UTF-8 */
- D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in UTF-8 */
-
- {D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."), /* "Тестовая Строка." in CP866 */
- D_STR_W_LEN("\x92\x85\x91\x92\x8e\x82\x80\x9f \x91\x92\x90\x8e\x8a\x80."), 1}, /* "ТЕСТОВАЯ СТРОКА." in CP866 */
- {D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."), /* "Тестовая Строка." in CP1251 */
- D_STR_W_LEN("\xd2\xc5\xd1\xd2\xce\xc2\xc0\xdf \xd1\xd2\xd0\xce\xca\xc0."), 1}, /* "ТЕСТОВАЯ СТРОКА." in CP1251 */
- {D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."), /* "Тестовая Строка." in KOI8-R */
- D_STR_W_LEN("\xf4\xe5\xf3\xf4\xef\xf7\xe1\xf1 \xf3\xf4\xf2\xef\xeb\xe1."), 1}, /* "ТЕСТОВАЯ СТРОКА." in KOI8-R */
- {D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."), /* "Тестовая Строка." in ISO-8859-5 */
- D_STR_W_LEN("\xc2\xb5\xc1\xc2\xbe\xb2\xb0\xcf \xc1\xc2\xc0\xbe\xba\xb0."), 1}, /* "ТЕСТОВАЯ СТРОКА." in ISO-8859-5 */
- {D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
- "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."), /* "Тестовая Строка." in UTF-8 */
- D_STR_W_LEN("\xd0\xa2\xd0\x95\xd0\xa1\xd0\xa2\xd0\x9e\xd0\x92\xd0\x90\xd0"
- "\xaf \xd0\xa1\xd0\xa2\xd0\xa0\xd0\x9e\xd0\x9a\xd0\x90."), 3} /* "ТЕСТОВАЯ СТРОКА." in UTF-8 */
+ {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN (
+ "1234567890!@~%&$@#{}[]\\/!?`"), 27},
+ {D_STR_W_LEN (".1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN (
+ "1234567890!@~%&$@#{}[]\\/!?`"), 0},
+ {D_STR_W_LEN ("Simple string."), D_STR_W_LEN ("Simple ctring."), 7},
+ {D_STR_W_LEN ("simple string."), D_STR_W_LEN ("simple string"), 13},
+ {D_STR_W_LEN ("simple strings"), D_STR_W_LEN ("Simple String."), 13},
+ {D_STR_W_LEN ("sImPlE StRiNg."), D_STR_W_LEN ("SYMpLe sTrInG."), 1},
+ {D_STR_W_LEN ("SIMPLE STRING."), D_STR_W_LEN ("simple string.2"), 14},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz,"), D_STR_W_LEN (
+ "abcdefghijklmnopqrstuvwxyz."), 26},
+ {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz!"), D_STR_W_LEN (
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ?"), 26},
+ {D_STR_W_LEN ("zyxwvutsrqponwMLKJIHGFEDCBA"), D_STR_W_LEN (
+ "ZYXWVUTSRQPON%mlkjihgfedcba"), 13},
+
+ {D_STR_W_LEN ("S\xbdur veulent plus d'\xbdufs."), /* "Sœur veulent plus d'œufs." in ISO-8859-15 */
+ D_STR_W_LEN ("S\xbcUR VEULENT PLUS D'\xbcUFS."), 1}, /* "SŒUR VEULENT PLUS D'ŒUFS." in ISO-8859-15 */
+ {D_STR_W_LEN ("S\x9cur veulent plus d'\x9cufs."), /* "Sœur veulent plus d'œufs." in CP1252 */
+ D_STR_W_LEN ("S\x8cUR VEULENT PLUS D'\x8cUFS."), 1}, /* "SŒUR VEULENT PLUS D'ŒUFS." in CP1252 */
+ {D_STR_W_LEN ("S\xc5\x93ur veulent plus d'\xc5\x93ufs."), /* "Sœur veulent plus d'œufs." in UTF-8 */
+ D_STR_W_LEN ("S\xc5\x92UR VEULENT PLUS D'\xc5\x92UFS."), 2}, /* "SŒUR VEULENT PLUS D'ŒUFS." in UTF-8 */
+
+ {D_STR_W_LEN ("Um ein sch\x94nes M\x84" "dchen zu k\x81ssen."), /* "Um ein schönes Mädchen zu küssen." in CP850 */
+ D_STR_W_LEN ("UM EIN SCH\x99NES M\x8e" "DCHEN ZU K\x9aSSEN."), 10}, /* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in CP850 */
+ {D_STR_W_LEN ("Um ein sch\xf6nes M\xe4" "dchen zu k\xfcssen."), /* "Um ein schönes Mädchen zu küssen." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
+ D_STR_W_LEN ("UM EIN SCH\xd6NES M\xc4" "DCHEN ZU K\xdcSSEN."), 10}, /* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
+ {D_STR_W_LEN ("Um ein sch\xc3\xb6nes M\xc3\xa4" "dchen zu k\xc3\xbcssen."), /* "Um ein schönes Mädchen zu küssen." in UTF-8 */
+ D_STR_W_LEN ("UM EIN SCH\xc3\x96NES M\xc3\x84" "DCHEN ZU K\xc3\x9cSSEN."),
+ 11}, /* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in UTF-8 */
+
+ {D_STR_W_LEN ("\x98stanbul"), /* "İstanbul" in CP857 */
+ D_STR_W_LEN ("istanbul"), 0}, /* "istanbul" in CP857 */
+ {D_STR_W_LEN ("\xddstanbul"), /* "İstanbul" in ISO-8859-9/CP1254 */
+ D_STR_W_LEN ("istanbul"), 0}, /* "istanbul" in ISO-8859-9/CP1254 */
+ {D_STR_W_LEN ("\xc4\xb0stanbul"), /* "İstanbul" in UTF-8 */
+ D_STR_W_LEN ("istanbul"), 0}, /* "istanbul" in UTF-8 */
+ {D_STR_W_LEN ("Diyarbak\x8dr"), /* "Diyarbakır" in CP857 */
+ D_STR_W_LEN ("DiyarbakIR"), 8}, /* "DiyarbakIR" in CP857 */
+ {D_STR_W_LEN ("Diyarbak\xfdr"), /* "Diyarbakır" in ISO-8859-9/CP1254 */
+ D_STR_W_LEN ("DiyarbakIR"), 8}, /* "DiyarbakIR" in ISO-8859-9/CP1254 */
+ {D_STR_W_LEN ("Diyarbak\xc4\xb1r"), /* "Diyarbakır" in UTF-8 */
+ D_STR_W_LEN ("DiyarbakIR"), 8}, /* "DiyarbakIR" in UTF-8 */
+
+ {D_STR_W_LEN ("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."), /* "Тестовая Строка." in CP866 */
+ D_STR_W_LEN ("\x92\x85\x91\x92\x8e\x82\x80\x9f \x91\x92\x90\x8e\x8a\x80."),
+ 1}, /* "ТЕСТОВАЯ СТРОКА." in CP866 */
+ {D_STR_W_LEN ("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."), /* "Тестовая Строка." in CP1251 */
+ D_STR_W_LEN ("\xd2\xc5\xd1\xd2\xce\xc2\xc0\xdf \xd1\xd2\xd0\xce\xca\xc0."),
+ 1}, /* "ТЕСТОВАЯ СТРОКА." in CP1251 */
+ {D_STR_W_LEN ("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."), /* "Тестовая Строка." in KOI8-R */
+ D_STR_W_LEN ("\xf4\xe5\xf3\xf4\xef\xf7\xe1\xf1 \xf3\xf4\xf2\xef\xeb\xe1."),
+ 1}, /* "ТЕСТОВАЯ СТРОКА." in KOI8-R */
+ {D_STR_W_LEN ("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."), /* "Тестовая Строка." in ISO-8859-5 */
+ D_STR_W_LEN ("\xc2\xb5\xc1\xc2\xbe\xb2\xb0\xcf \xc1\xc2\xc0\xbe\xba\xb0."),
+ 1}, /* "ТЕСТОВАЯ СТРОКА." in ISO-8859-5 */
+ {D_STR_W_LEN ("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
+ "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."), /* "Тестовая Строка." in UTF-8 */
+ D_STR_W_LEN ("\xd0\xa2\xd0\x95\xd0\xa1\xd0\xa2\xd0\x9e\xd0\x92\xd0\x90\xd0"
+ "\xaf \xd0\xa1\xd0\xa2\xd0\xa0\xd0\x9e\xd0\x9a\xd0\x90."), 3} /* "ТЕСТОВАЯ СТРОКА." in UTF-8 */
};
-int check_eq_strings(void)
+int
+check_eq_strings (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(eq_strings) / sizeof(eq_strings[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- const struct two_eq_strs * const t = eq_strings + i;
- if (c_failed[i])
- continue; /* skip already failed checks */
- if (!MHD_str_equal_caseless_(t->s1.str, t->s2.str))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
- " Locale: %s\n", n_prnt(t->s1.str), n_prnt(t->s2.str), get_current_locale_str());
- }
- else if (!MHD_str_equal_caseless_(t->s2.str, t->s1.str))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
- " Locale: %s\n", n_prnt(t->s2.str), n_prnt(t->s1.str), get_current_locale_str());
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") != 0 && \\\n"
- " MHD_str_equal_caseless_(\"%s\", \"%s\") != 0\n", n_prnt(t->s1.str), n_prnt(t->s2.str),
- n_prnt(t->s2.str), n_prnt(t->s1.str));
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ const struct two_eq_strs *const t = eq_strings + i;
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+ if (! MHD_str_equal_caseless_ (t->s1.str, t->s2.str))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
+ " Locale: %s\n", n_prnt (t->s1.str), n_prnt (t->s2.str),
+ get_current_locale_str ());
+ }
+ else if (! MHD_str_equal_caseless_ (t->s2.str, t->s1.str))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
+ " Locale: %s\n", n_prnt (t->s2.str), n_prnt (t->s1.str),
+ get_current_locale_str ());
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf ("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") != 0 && \\\n"
+ " MHD_str_equal_caseless_(\"%s\", \"%s\") != 0\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str),
+ n_prnt (t->s2.str), n_prnt (t->s1.str));
}
+ }
return t_failed;
}
-int check_neq_strings(void)
+
+int
+check_neq_strings (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(neq_strings) / sizeof(neq_strings[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- const struct two_neq_strs * const t = neq_strings + i;
- if (c_failed[i])
- continue; /* skip already failed checks */
- if (MHD_str_equal_caseless_(t->s1.str, t->s2.str))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
- " Locale: %s\n", n_prnt(t->s1.str), n_prnt(t->s2.str), get_current_locale_str());
- }
- else if (MHD_str_equal_caseless_(t->s2.str, t->s1.str))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
- " Locale: %s\n", n_prnt(t->s2.str), n_prnt(t->s1.str), get_current_locale_str());
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") == 0 && \\\n"
- " MHD_str_equal_caseless_(\"%s\", \"%s\") == 0\n", n_prnt(t->s1.str), n_prnt(t->s2.str),
- n_prnt(t->s2.str), n_prnt(t->s1.str));
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ const struct two_neq_strs *const t = neq_strings + i;
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+ if (MHD_str_equal_caseless_ (t->s1.str, t->s2.str))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
+ " Locale: %s\n", n_prnt (t->s1.str), n_prnt (t->s2.str),
+ get_current_locale_str ());
+ }
+ else if (MHD_str_equal_caseless_ (t->s2.str, t->s1.str))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
+ " Locale: %s\n", n_prnt (t->s2.str), n_prnt (t->s1.str),
+ get_current_locale_str ());
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf ("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") == 0 && \\\n"
+ " MHD_str_equal_caseless_(\"%s\", \"%s\") == 0\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str),
+ n_prnt (t->s2.str), n_prnt (t->s1.str));
}
+ }
return t_failed;
}
-int check_eq_strings_n(void)
+
+int
+check_eq_strings_n (void)
{
size_t t_failed = 0;
size_t i, j, k;
static const size_t n_checks = sizeof(eq_strings) / sizeof(eq_strings[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t m_len;
- const struct two_eq_strs * const t = eq_strings + i;
- m_len = (t->s1.len > t->s2.len) ? t->s1.len : t->s2.len;
- for(k = 0; k <= m_len + 1 && !c_failed[i]; k++)
- {
- if (!MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
- " while expected non-zero. Locale: %s\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
- }
- else if (!MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
- " while expected non-zero. Locale: %s\n",
- n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
- " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) m_len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t m_len;
+ const struct two_eq_strs *const t = eq_strings + i;
+ m_len = (t->s1.len > t->s2.len) ? t->s1.len : t->s2.len;
+ for (k = 0; k <= m_len + 1 && ! c_failed[i]; k++)
+ {
+ if (! MHD_str_equal_caseless_n_ (t->s1.str, t->s2.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
+ " while expected non-zero. Locale: %s\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ else if (! MHD_str_equal_caseless_n_ (t->s2.str, t->s1.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
+ " while expected non-zero. Locale: %s\n",
+ n_prnt (t->s2.str), n_prnt (t->s1.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
+ " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), n_prnt (t->s2.str),
+ n_prnt (t->s1.str), (unsigned int) m_len + 1);
}
+ }
return t_failed;
}
-int check_neq_strings_n(void)
+
+int
+check_neq_strings_n (void)
{
size_t t_failed = 0;
size_t i, j, k;
static const size_t n_checks = sizeof(neq_strings) / sizeof(neq_strings[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t m_len;
- const struct two_neq_strs * const t = neq_strings + i;
- m_len = t->s1.len > t->s2.len ? t->s1.len : t->s2.len;
- if (t->dif_pos >= m_len)
- {
- fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less than "
- "s1.len (%u) or s2.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
- (unsigned int) t->s1.len, (unsigned int) t->s2.len);
- return -1;
- }
- if (t->dif_pos > t->s1.len)
- {
- fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
- "equal to s1.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
- (unsigned int) t->s1.len);
- return -1;
- }
- if (t->dif_pos > t->s2.len)
- {
- fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
- "equal to s2.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
- (unsigned int) t->s2.len);
- return -1;
- }
- for(k = 0; k <= m_len + 1 && !c_failed[i]; k++)
- {
- if (k <= t->dif_pos)
- {
- if (!MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
- " while expected non-zero. Locale: %s\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
- }
- else if (!MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
- " while expected non-zero. Locale: %s\n",
- n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
- }
- }
- else
- {
- if (MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
- " while expected zero. Locale: %s\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
- }
- else if (MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
- " while expected zero. Locale: %s\n",
- n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- {
- printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
- " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str),
- (unsigned int) t->dif_pos);
-
- printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0 && \\\n"
- " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0, where N is %u..%u\n",
- n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str),
- (unsigned int) t->dif_pos + 1, (unsigned int) m_len + 1);
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t m_len;
+ const struct two_neq_strs *const t = neq_strings + i;
+ m_len = t->s1.len > t->s2.len ? t->s1.len : t->s2.len;
+ if (t->dif_pos >= m_len)
+ {
+ fprintf (stderr,
+ "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less than "
+ "s1.len (%u) or s2.len (%u).\n", (unsigned int) i, (unsigned
+ int) t->
+ dif_pos,
+ (unsigned int) t->s1.len, (unsigned int) t->s2.len);
+ return -1;
+ }
+ if (t->dif_pos > t->s1.len)
+ {
+ fprintf (stderr,
+ "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
+ "equal to s1.len (%u).\n", (unsigned int) i, (unsigned
+ int) t->dif_pos,
+ (unsigned int) t->s1.len);
+ return -1;
+ }
+ if (t->dif_pos > t->s2.len)
+ {
+ fprintf (stderr,
+ "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
+ "equal to s2.len (%u).\n", (unsigned int) i, (unsigned
+ int) t->dif_pos,
+ (unsigned int) t->s2.len);
+ return -1;
+ }
+ for (k = 0; k <= m_len + 1 && ! c_failed[i]; k++)
+ {
+ if (k <= t->dif_pos)
+ {
+ if (! MHD_str_equal_caseless_n_ (t->s1.str, t->s2.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
+ " while expected non-zero. Locale: %s\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ else if (! MHD_str_equal_caseless_n_ (t->s2.str, t->s1.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
+ " while expected non-zero. Locale: %s\n",
+ n_prnt (t->s2.str), n_prnt (t->s1.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ }
+ else
+ {
+ if (MHD_str_equal_caseless_n_ (t->s1.str, t->s2.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
+ " while expected zero. Locale: %s\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ else if (MHD_str_equal_caseless_n_ (t->s2.str, t->s1.str, k))
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
+ " while expected zero. Locale: %s\n",
+ n_prnt (t->s2.str), n_prnt (t->s1.str), (unsigned int) k,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ {
+ printf (
+ "PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
+ " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), n_prnt (t->s2.str),
+ n_prnt (t->s1.str),
+ (unsigned int) t->dif_pos);
+
+ printf (
+ "PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0 && \\\n"
+ " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0, where N is %u..%u\n",
+ n_prnt (t->s1.str), n_prnt (t->s2.str), n_prnt (t->s2.str),
+ n_prnt (t->s1.str),
+ (unsigned int) t->dif_pos + 1, (unsigned int) m_len + 1);
+ }
}
+ }
return t_failed;
}
+
/*
* Run eq/neq strings tests
*/
-int run_eq_neq_str_tests(void)
+int
+run_eq_neq_str_tests (void)
{
int str_equal_caseless_fails = 0;
int str_equal_caseless_n_fails = 0;
int res;
- res = check_eq_strings();
+ res = check_eq_strings ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_eq_strings().\n");
- return 99;
- }
- str_equal_caseless_fails += res;
- fprintf(stderr, "FAILED: testcase check_eq_strings() failed.\n\n");
+ fprintf (stderr, "ERROR: test internal error in check_eq_strings().\n");
+ return 99;
}
+ str_equal_caseless_fails += res;
+ fprintf (stderr, "FAILED: testcase check_eq_strings() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_eq_strings() successfully passed.\n\n");
+ printf ("PASSED: testcase check_eq_strings() successfully passed.\n\n");
- res = check_neq_strings();
+ res = check_neq_strings ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_neq_strings().\n");
- return 99;
- }
- str_equal_caseless_fails += res;
- fprintf(stderr, "FAILED: testcase check_neq_strings() failed.\n\n");
+ fprintf (stderr, "ERROR: test internal error in check_neq_strings().\n");
+ return 99;
}
+ str_equal_caseless_fails += res;
+ fprintf (stderr, "FAILED: testcase check_neq_strings() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_neq_strings() successfully passed.\n\n");
+ printf ("PASSED: testcase check_neq_strings() successfully passed.\n\n");
if (str_equal_caseless_fails)
- fprintf(stderr, "FAILED: function MHD_str_equal_caseless_() failed %d time%s.\n\n",
- str_equal_caseless_fails, str_equal_caseless_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_str_equal_caseless_() failed %d time%s.\n\n",
+ str_equal_caseless_fails, str_equal_caseless_fails == 1 ? "" :
+ "s");
else if (verbose > 0)
- printf("PASSED: function MHD_str_equal_caseless_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_str_equal_caseless_() successfully passed all checks.\n\n");
- res = check_eq_strings_n();
+ res = check_eq_strings_n ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_eq_strings_n().\n");
- return 99;
- }
- str_equal_caseless_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_eq_strings_n() failed.\n\n");
+ fprintf (stderr, "ERROR: test internal error in check_eq_strings_n().\n");
+ return 99;
}
+ str_equal_caseless_n_fails += res;
+ fprintf (stderr, "FAILED: testcase check_eq_strings_n() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_eq_strings_n() successfully passed.\n\n");
+ printf ("PASSED: testcase check_eq_strings_n() successfully passed.\n\n");
- res = check_neq_strings_n();
+ res = check_neq_strings_n ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_neq_strings_n().\n");
- return 99;
- }
- str_equal_caseless_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_neq_strings_n() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_neq_strings_n().\n");
+ return 99;
}
+ str_equal_caseless_n_fails += res;
+ fprintf (stderr, "FAILED: testcase check_neq_strings_n() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_neq_strings_n() successfully passed.\n\n");
+ printf ("PASSED: testcase check_neq_strings_n() successfully passed.\n\n");
if (str_equal_caseless_n_fails)
- fprintf(stderr, "FAILED: function MHD_str_equal_caseless_n_() failed %d time%s.\n\n",
- str_equal_caseless_n_fails, str_equal_caseless_n_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_str_equal_caseless_n_() failed %d time%s.\n\n",
+ str_equal_caseless_n_fails, str_equal_caseless_n_fails == 1 ? "" :
+ "s");
else if (verbose > 0)
- printf("PASSED: function MHD_str_equal_caseless_n_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_str_equal_caseless_n_() successfully passed all checks.\n\n");
if (str_equal_caseless_fails || str_equal_caseless_n_fails)
- {
- if (verbose > 0)
- printf("At least one test failed.\n");
+ {
+ if (verbose > 0)
+ printf ("At least one test failed.\n");
- return 1;
- }
+ return 1;
+ }
if (verbose > 0)
- printf("All tests passed successfully.\n");
+ printf ("All tests passed successfully.\n");
return 0;
}
+
/*
* Digits in string -> value tests
*/
-struct str_with_value {
+struct str_with_value
+{
const struct str_with_len str;
const size_t num_of_digt;
const uint64_t val;
@@ -798,1646 +879,1959 @@
/* valid string for conversion to unsigned integer value */
static const struct str_with_value dstrs_w_values[] = {
- /* simplest strings */
- {D_STR_W_LEN("1"), 1, 1},
- {D_STR_W_LEN("0"), 1, 0},
- {D_STR_W_LEN("10000"), 5, 10000},
-
- /* all digits */
- {D_STR_W_LEN("1234"), 4, 1234},
- {D_STR_W_LEN("4567"), 4, 4567},
- {D_STR_W_LEN("7890"), 4, 7890},
- {D_STR_W_LEN("8021"), 4, 8021},
- {D_STR_W_LEN("9754"), 4, 9754},
- {D_STR_W_LEN("6392"), 4, 6392},
-
- /* various prefixes */
- {D_STR_W_LEN("00000000"), 8, 0},
- {D_STR_W_LEN("0755"), 4, 755}, /* not to be interpreted as octal value! */
- {D_STR_W_LEN("002"), 3, 2},
- {D_STR_W_LEN("0001"), 4, 1},
- {D_STR_W_LEN("00000000000000000000000031295483"), 32, 31295483},
-
- /* numbers below and above limits */
- {D_STR_W_LEN("127"), 3, 127}, /* 0x7F, SCHAR_MAX */
- {D_STR_W_LEN("128"), 3, 128}, /* 0x80, SCHAR_MAX+1 */
- {D_STR_W_LEN("255"), 3, 255}, /* 0xFF, UCHAR_MAX */
- {D_STR_W_LEN("256"), 3, 256}, /* 0x100, UCHAR_MAX+1 */
- {D_STR_W_LEN("32767"), 5, 32767}, /* 0x7FFF, INT16_MAX */
- {D_STR_W_LEN("32768"), 5, 32768}, /* 0x8000, INT16_MAX+1 */
- {D_STR_W_LEN("65535"), 5, 65535}, /* 0xFFFF, UINT16_MAX */
- {D_STR_W_LEN("65536"), 5, 65536}, /* 0x10000, UINT16_MAX+1 */
- {D_STR_W_LEN("2147483647"), 10, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
- {D_STR_W_LEN("2147483648"), 10, UINT64_C(2147483648)}, /* 0x80000000, INT32_MAX+1 */
- {D_STR_W_LEN("4294967295"), 10, UINT64_C(4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
- {D_STR_W_LEN("4294967296"), 10, UINT64_C(4294967296)}, /* 0x100000000, UINT32_MAX+1 */
- {D_STR_W_LEN("9223372036854775807"), 19, UINT64_C(9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
- {D_STR_W_LEN("9223372036854775808"), 19, UINT64_C(9223372036854775808)}, /* 0x8000000000000000, INT64_MAX+1 */
- {D_STR_W_LEN("18446744073709551615"), 20, UINT64_C(18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
-
- /* random numbers */
- {D_STR_W_LEN("10186753"), 8, 10186753},
- {D_STR_W_LEN("144402566"), 9, 144402566},
- {D_STR_W_LEN("151903144"), 9, 151903144},
- {D_STR_W_LEN("139264621"), 9, 139264621},
- {D_STR_W_LEN("730348"), 6, 730348},
- {D_STR_W_LEN("21584377"), 8, 21584377},
- {D_STR_W_LEN("709"), 3, 709},
- {D_STR_W_LEN("54"), 2, 54},
- {D_STR_W_LEN("8452"), 4, 8452},
- {D_STR_W_LEN("17745098750013624977"), 20, UINT64_C(17745098750013624977)},
- {D_STR_W_LEN("06786878769931678000"), 20, UINT64_C(6786878769931678000)},
-
- /* non-digit suffixes */
- {D_STR_W_LEN("1234oa"), 4, 1234},
- {D_STR_W_LEN("20h"), 2, 20}, /* not to be interpreted as hex value! */
- {D_STR_W_LEN("0x1F"), 1, 0}, /* not to be interpreted as hex value! */
- {D_STR_W_LEN("0564`~}"), 4, 564},
- {D_STR_W_LEN("7240146.724"), 7, 7240146},
- {D_STR_W_LEN("2,9"), 1, 2},
- {D_STR_W_LEN("200+1"), 3, 200},
- {D_STR_W_LEN("1a"), 1, 1},
- {D_STR_W_LEN("2E"), 1, 2},
- {D_STR_W_LEN("6c"), 1, 6},
- {D_STR_W_LEN("8F"), 1, 8},
- {D_STR_W_LEN("287416997! And the not too long string."), 9, 287416997}
+ /* simplest strings */
+ {D_STR_W_LEN ("1"), 1, 1},
+ {D_STR_W_LEN ("0"), 1, 0},
+ {D_STR_W_LEN ("10000"), 5, 10000},
+
+ /* all digits */
+ {D_STR_W_LEN ("1234"), 4, 1234},
+ {D_STR_W_LEN ("4567"), 4, 4567},
+ {D_STR_W_LEN ("7890"), 4, 7890},
+ {D_STR_W_LEN ("8021"), 4, 8021},
+ {D_STR_W_LEN ("9754"), 4, 9754},
+ {D_STR_W_LEN ("6392"), 4, 6392},
+
+ /* various prefixes */
+ {D_STR_W_LEN ("00000000"), 8, 0},
+ {D_STR_W_LEN ("0755"), 4, 755}, /* not to be interpreted as octal value! */
+ {D_STR_W_LEN ("002"), 3, 2},
+ {D_STR_W_LEN ("0001"), 4, 1},
+ {D_STR_W_LEN ("00000000000000000000000031295483"), 32, 31295483},
+
+ /* numbers below and above limits */
+ {D_STR_W_LEN ("127"), 3, 127}, /* 0x7F, SCHAR_MAX */
+ {D_STR_W_LEN ("128"), 3, 128}, /* 0x80, SCHAR_MAX+1 */
+ {D_STR_W_LEN ("255"), 3, 255}, /* 0xFF, UCHAR_MAX */
+ {D_STR_W_LEN ("256"), 3, 256}, /* 0x100, UCHAR_MAX+1 */
+ {D_STR_W_LEN ("32767"), 5, 32767}, /* 0x7FFF, INT16_MAX */
+ {D_STR_W_LEN ("32768"), 5, 32768}, /* 0x8000, INT16_MAX+1 */
+ {D_STR_W_LEN ("65535"), 5, 65535}, /* 0xFFFF, UINT16_MAX */
+ {D_STR_W_LEN ("65536"), 5, 65536}, /* 0x10000, UINT16_MAX+1 */
+ {D_STR_W_LEN ("2147483647"), 10, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
+ {D_STR_W_LEN ("2147483648"), 10, UINT64_C (2147483648)}, /* 0x80000000, INT32_MAX+1 */
+ {D_STR_W_LEN ("4294967295"), 10, UINT64_C (4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
+ {D_STR_W_LEN ("4294967296"), 10, UINT64_C (4294967296)}, /* 0x100000000, UINT32_MAX+1 */
+ {D_STR_W_LEN ("9223372036854775807"), 19, UINT64_C (9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
+ {D_STR_W_LEN ("9223372036854775808"), 19, UINT64_C (9223372036854775808)}, /* 0x8000000000000000, INT64_MAX+1 */
+ {D_STR_W_LEN ("18446744073709551615"), 20, UINT64_C (18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
+
+ /* random numbers */
+ {D_STR_W_LEN ("10186753"), 8, 10186753},
+ {D_STR_W_LEN ("144402566"), 9, 144402566},
+ {D_STR_W_LEN ("151903144"), 9, 151903144},
+ {D_STR_W_LEN ("139264621"), 9, 139264621},
+ {D_STR_W_LEN ("730348"), 6, 730348},
+ {D_STR_W_LEN ("21584377"), 8, 21584377},
+ {D_STR_W_LEN ("709"), 3, 709},
+ {D_STR_W_LEN ("54"), 2, 54},
+ {D_STR_W_LEN ("8452"), 4, 8452},
+ {D_STR_W_LEN ("17745098750013624977"), 20, UINT64_C (17745098750013624977)},
+ {D_STR_W_LEN ("06786878769931678000"), 20, UINT64_C (6786878769931678000)},
+
+ /* non-digit suffixes */
+ {D_STR_W_LEN ("1234oa"), 4, 1234},
+ {D_STR_W_LEN ("20h"), 2, 20}, /* not to be interpreted as hex value! */
+ {D_STR_W_LEN ("0x1F"), 1, 0}, /* not to be interpreted as hex value! */
+ {D_STR_W_LEN ("0564`~}"), 4, 564},
+ {D_STR_W_LEN ("7240146.724"), 7, 7240146},
+ {D_STR_W_LEN ("2,9"), 1, 2},
+ {D_STR_W_LEN ("200+1"), 3, 200},
+ {D_STR_W_LEN ("1a"), 1, 1},
+ {D_STR_W_LEN ("2E"), 1, 2},
+ {D_STR_W_LEN ("6c"), 1, 6},
+ {D_STR_W_LEN ("8F"), 1, 8},
+ {D_STR_W_LEN ("287416997! And the not too long string."), 9, 287416997}
};
/* strings that should overflow uint64_t */
const struct str_with_len str_ovflw[] = {
- D_STR_W_LEN("18446744073709551616"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("18446744073709551620"),
- D_STR_W_LEN("18446744083709551615"),
- D_STR_W_LEN("19234761020556472143"),
- D_STR_W_LEN("184467440737095516150"),
- D_STR_W_LEN("1844674407370955161500"),
- D_STR_W_LEN("000018446744073709551616"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("20000000000000000000"),
- D_STR_W_LEN("020000000000000000000"),
- D_STR_W_LEN("0020000000000000000000"),
- D_STR_W_LEN("100000000000000000000"),
- D_STR_W_LEN("434532891232591226417"),
- D_STR_W_LEN("99999999999999999999"),
- D_STR_W_LEN("18446744073709551616abcd"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("20000000000000000000 suffix"),
- D_STR_W_LEN("020000000000000000000x")
+ D_STR_W_LEN ("18446744073709551616"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("18446744073709551620"),
+ D_STR_W_LEN ("18446744083709551615"),
+ D_STR_W_LEN ("19234761020556472143"),
+ D_STR_W_LEN ("184467440737095516150"),
+ D_STR_W_LEN ("1844674407370955161500"),
+ D_STR_W_LEN ("000018446744073709551616"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("20000000000000000000"),
+ D_STR_W_LEN ("020000000000000000000"),
+ D_STR_W_LEN ("0020000000000000000000"),
+ D_STR_W_LEN ("100000000000000000000"),
+ D_STR_W_LEN ("434532891232591226417"),
+ D_STR_W_LEN ("99999999999999999999"),
+ D_STR_W_LEN ("18446744073709551616abcd"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("20000000000000000000 suffix"),
+ D_STR_W_LEN ("020000000000000000000x")
};
/* strings that should not be convertible to numeric value */
const struct str_with_len str_no_num[] = {
- D_STR_W_LEN("zero"),
- D_STR_W_LEN("one"),
- D_STR_W_LEN("\xb9\xb2\xb3"), /* superscript "123" in ISO-8859-1/CP1252 */
- D_STR_W_LEN("\xc2\xb9\xc2\xb2\xc2\xb3"), /* superscript "123" in UTF-8 */
- D_STR_W_LEN("\xd9\xa1\xd9\xa2\xd9\xa3"), /* Arabic-Indic "١٢٣" in UTF-8 */
- D_STR_W_LEN("\xdb\xb1\xdb\xb2\xdb\xb3"), /* Ext Arabic-Indic "۱۲۳" in UTF-8 */
- D_STR_W_LEN("\xe0\xa5\xa7\xe0\xa5\xa8\xe0\xa5\xa9"), /* Devanagari "१२३" in UTF-8 */
- D_STR_W_LEN("\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89"), /* Chinese "一二三" in UTF-8 */
- D_STR_W_LEN("\xd2\xbb\xb6\xfe\xc8\xfd"), /* Chinese "一二三" in GB2312/CP936 */
- D_STR_W_LEN("\x1B\x24\x29\x41\x0E\x52\x3B\x36\x7E\x48\x7D\x0F") /* Chinese "一二三" in ISO-2022-CN */
+ D_STR_W_LEN ("zero"),
+ D_STR_W_LEN ("one"),
+ D_STR_W_LEN ("\xb9\xb2\xb3"), /* superscript "123" in ISO-8859-1/CP1252 */
+ D_STR_W_LEN ("\xc2\xb9\xc2\xb2\xc2\xb3"), /* superscript "123" in UTF-8 */
+ D_STR_W_LEN ("\xd9\xa1\xd9\xa2\xd9\xa3"), /* Arabic-Indic "١٢٣" in UTF-8 */
+ D_STR_W_LEN ("\xdb\xb1\xdb\xb2\xdb\xb3"), /* Ext Arabic-Indic "۱۲۳" in UTF-8 */
+ D_STR_W_LEN ("\xe0\xa5\xa7\xe0\xa5\xa8\xe0\xa5\xa9"), /* Devanagari "१२३" in UTF-8 */
+ D_STR_W_LEN ("\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89"), /* Chinese "一二三" in UTF-8 */
+ D_STR_W_LEN ("\xd2\xbb\xb6\xfe\xc8\xfd"), /* Chinese "一二三" in GB2312/CP936 */
+ D_STR_W_LEN ("\x1B\x24\x29\x41\x0E\x52\x3B\x36\x7E\x48\x7D\x0F") /* Chinese "一二三" in ISO-2022-CN */
};
/* valid hex string for conversion to unsigned integer value */
static const struct str_with_value xdstrs_w_values[] = {
- /* simplest strings */
- {D_STR_W_LEN("1"), 1, 0x1},
- {D_STR_W_LEN("0"), 1, 0x0},
- {D_STR_W_LEN("10000"), 5, 0x10000},
-
- /* all digits */
- {D_STR_W_LEN("1234"), 4, 0x1234},
- {D_STR_W_LEN("4567"), 4, 0x4567},
- {D_STR_W_LEN("7890"), 4, 0x7890},
- {D_STR_W_LEN("8021"), 4, 0x8021},
- {D_STR_W_LEN("9754"), 4, 0x9754},
- {D_STR_W_LEN("6392"), 4, 0x6392},
- {D_STR_W_LEN("abcd"), 4, 0xABCD},
- {D_STR_W_LEN("cdef"), 4, 0xCDEF},
- {D_STR_W_LEN("FEAB"), 4, 0xFEAB},
- {D_STR_W_LEN("BCED"), 4, 0xBCED},
- {D_STR_W_LEN("bCeD"), 4, 0xBCED},
- {D_STR_W_LEN("1A5F"), 4, 0x1A5F},
- {D_STR_W_LEN("12AB"), 4, 0x12AB},
- {D_STR_W_LEN("CD34"), 4, 0xCD34},
- {D_STR_W_LEN("56EF"), 4, 0x56EF},
- {D_STR_W_LEN("7a9f"), 4, 0x7A9F},
-
- /* various prefixes */
- {D_STR_W_LEN("00000000"), 8, 0x0},
- {D_STR_W_LEN("0755"), 4, 0x755}, /* not to be interpreted as octal value! */
- {D_STR_W_LEN("002"), 3, 0x2},
- {D_STR_W_LEN("0001"), 4, 0x1},
- {D_STR_W_LEN("00a"), 3, 0xA},
- {D_STR_W_LEN("0F"), 2, 0xF},
- {D_STR_W_LEN("0000000000000000000000003A29e4C3"), 32, 0x3A29E4C3},
-
- /* numbers below and above limits */
- {D_STR_W_LEN("7F"), 2, 127}, /* 0x7F, SCHAR_MAX */
- {D_STR_W_LEN("7f"), 2, 127}, /* 0x7F, SCHAR_MAX */
- {D_STR_W_LEN("80"), 2, 128}, /* 0x80, SCHAR_MAX+1 */
- {D_STR_W_LEN("fF"), 2, 255}, /* 0xFF, UCHAR_MAX */
- {D_STR_W_LEN("Ff"), 2, 255}, /* 0xFF, UCHAR_MAX */
- {D_STR_W_LEN("FF"), 2, 255}, /* 0xFF, UCHAR_MAX */
- {D_STR_W_LEN("ff"), 2, 255}, /* 0xFF, UCHAR_MAX */
- {D_STR_W_LEN("100"), 3, 256}, /* 0x100, UCHAR_MAX+1 */
- {D_STR_W_LEN("7fff"), 4, 32767}, /* 0x7FFF, INT16_MAX */
- {D_STR_W_LEN("7FFF"), 4, 32767}, /* 0x7FFF, INT16_MAX */
- {D_STR_W_LEN("7Fff"), 4, 32767}, /* 0x7FFF, INT16_MAX */
- {D_STR_W_LEN("8000"), 4, 32768}, /* 0x8000, INT16_MAX+1 */
- {D_STR_W_LEN("ffff"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
- {D_STR_W_LEN("FFFF"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
- {D_STR_W_LEN("FffF"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
- {D_STR_W_LEN("10000"), 5, 65536}, /* 0x10000, UINT16_MAX+1 */
- {D_STR_W_LEN("7FFFFFFF"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
- {D_STR_W_LEN("7fffffff"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
- {D_STR_W_LEN("7FFffFff"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
- {D_STR_W_LEN("80000000"), 8, UINT64_C(2147483648)}, /* 0x80000000, INT32_MAX+1 */
- {D_STR_W_LEN("FFFFFFFF"), 8, UINT64_C(4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
- {D_STR_W_LEN("ffffffff"), 8, UINT64_C(4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
- {D_STR_W_LEN("FfFfFfFf"), 8, UINT64_C(4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
- {D_STR_W_LEN("100000000"), 9, UINT64_C(4294967296)}, /* 0x100000000, UINT32_MAX+1 */
- {D_STR_W_LEN("7fffffffffffffff"), 16, UINT64_C(9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
- {D_STR_W_LEN("7FFFFFFFFFFFFFFF"), 16, UINT64_C(9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
- {D_STR_W_LEN("7FfffFFFFffFFffF"), 16, UINT64_C(9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
- {D_STR_W_LEN("8000000000000000"), 16, UINT64_C(9223372036854775808)}, /* 0x8000000000000000, INT64_MAX+1 */
- {D_STR_W_LEN("ffffffffffffffff"), 16, UINT64_C(18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
- {D_STR_W_LEN("FFFFFFFFFFFFFFFF"), 16, UINT64_C(18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
- {D_STR_W_LEN("FffFffFFffFFfFFF"), 16, UINT64_C(18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
-
- /* random numbers */
- {D_STR_W_LEN("10186753"), 8, 0x10186753},
- {D_STR_W_LEN("144402566"), 9, 0x144402566},
- {D_STR_W_LEN("151903144"), 9, 0x151903144},
- {D_STR_W_LEN("139264621"), 9, 0x139264621},
- {D_STR_W_LEN("730348"), 6, 0x730348},
- {D_STR_W_LEN("21584377"), 8, 0x21584377},
- {D_STR_W_LEN("709"), 3, 0x709},
- {D_STR_W_LEN("54"), 2, 0x54},
- {D_STR_W_LEN("8452"), 4, 0x8452},
- {D_STR_W_LEN("22353EC6"), 8, 0x22353EC6},
- {D_STR_W_LEN("307F1655"), 8, 0x307F1655},
- {D_STR_W_LEN("1FCB7226"), 8, 0x1FCB7226},
- {D_STR_W_LEN("82480560"), 8, 0x82480560},
- {D_STR_W_LEN("7386D95"), 7, 0x7386D95},
- {D_STR_W_LEN("EC3AB"), 5, 0xEC3AB},
- {D_STR_W_LEN("6DD05"), 5, 0x6DD05},
- {D_STR_W_LEN("C5DF"), 4, 0xC5DF},
- {D_STR_W_LEN("6CE"), 3, 0x6CE},
- {D_STR_W_LEN("CE6"), 3, 0xCE6},
- {D_STR_W_LEN("ce6"), 3, 0xCE6},
- {D_STR_W_LEN("F27"), 3, 0xF27},
- {D_STR_W_LEN("8497D54277D7E1"), 14, UINT64_C(37321639124785121)},
- {D_STR_W_LEN("8497d54277d7e1"), 14, UINT64_C(37321639124785121)},
- {D_STR_W_LEN("8497d54277d7E1"), 14, UINT64_C(37321639124785121)},
- {D_STR_W_LEN("8C8112D0A06"), 11, UINT64_C(9655374645766)},
- {D_STR_W_LEN("8c8112d0a06"), 11, UINT64_C(9655374645766)},
- {D_STR_W_LEN("8c8112d0A06"), 11, UINT64_C(9655374645766)},
- {D_STR_W_LEN("1774509875001362"), 16, UINT64_C(1690064375898968930)},
- {D_STR_W_LEN("0678687876998000"), 16, UINT64_C(466237428027981824)},
-
- /* non-digit suffixes */
- {D_STR_W_LEN("1234oa"), 4, 0x1234},
- {D_STR_W_LEN("20h"), 2, 0x20},
- {D_STR_W_LEN("2CH"), 2, 0x2C},
- {D_STR_W_LEN("2ch"), 2, 0x2C},
- {D_STR_W_LEN("0x1F"), 1, 0x0}, /* not to be interpreted as hex prefix! */
- {D_STR_W_LEN("0564`~}"), 4, 0x564},
- {D_STR_W_LEN("0A64`~}"), 4, 0xA64},
- {D_STR_W_LEN("056c`~}"), 4, 0X56C},
- {D_STR_W_LEN("7240146.724"), 7, 0x7240146},
- {D_STR_W_LEN("7E4c1AB.724"), 7, 0X7E4C1AB},
- {D_STR_W_LEN("F24B1B6.724"), 7, 0xF24B1B6},
- {D_STR_W_LEN("2,9"), 1, 0x2},
- {D_STR_W_LEN("a,9"), 1, 0xA},
- {D_STR_W_LEN("200+1"), 3, 0x200},
- {D_STR_W_LEN("2cc+1"), 3, 0x2CC},
- {D_STR_W_LEN("2cC+1"), 3, 0x2CC},
- {D_STR_W_LEN("27416997! And the not too long string."), 8, 0x27416997},
- {D_STR_W_LEN("27555416997! And the not too long string."), 11, 0x27555416997},
- {D_STR_W_LEN("416997And the not too long string."), 7, 0x416997A},
- {D_STR_W_LEN("0F4C3Dabstract addition to make string even longer"), 8, 0xF4C3DAB}
+ /* simplest strings */
+ {D_STR_W_LEN ("1"), 1, 0x1},
+ {D_STR_W_LEN ("0"), 1, 0x0},
+ {D_STR_W_LEN ("10000"), 5, 0x10000},
+
+ /* all digits */
+ {D_STR_W_LEN ("1234"), 4, 0x1234},
+ {D_STR_W_LEN ("4567"), 4, 0x4567},
+ {D_STR_W_LEN ("7890"), 4, 0x7890},
+ {D_STR_W_LEN ("8021"), 4, 0x8021},
+ {D_STR_W_LEN ("9754"), 4, 0x9754},
+ {D_STR_W_LEN ("6392"), 4, 0x6392},
+ {D_STR_W_LEN ("abcd"), 4, 0xABCD},
+ {D_STR_W_LEN ("cdef"), 4, 0xCDEF},
+ {D_STR_W_LEN ("FEAB"), 4, 0xFEAB},
+ {D_STR_W_LEN ("BCED"), 4, 0xBCED},
+ {D_STR_W_LEN ("bCeD"), 4, 0xBCED},
+ {D_STR_W_LEN ("1A5F"), 4, 0x1A5F},
+ {D_STR_W_LEN ("12AB"), 4, 0x12AB},
+ {D_STR_W_LEN ("CD34"), 4, 0xCD34},
+ {D_STR_W_LEN ("56EF"), 4, 0x56EF},
+ {D_STR_W_LEN ("7a9f"), 4, 0x7A9F},
+
+ /* various prefixes */
+ {D_STR_W_LEN ("00000000"), 8, 0x0},
+ {D_STR_W_LEN ("0755"), 4, 0x755}, /* not to be interpreted as octal value! */
+ {D_STR_W_LEN ("002"), 3, 0x2},
+ {D_STR_W_LEN ("0001"), 4, 0x1},
+ {D_STR_W_LEN ("00a"), 3, 0xA},
+ {D_STR_W_LEN ("0F"), 2, 0xF},
+ {D_STR_W_LEN ("0000000000000000000000003A29e4C3"), 32, 0x3A29E4C3},
+
+ /* numbers below and above limits */
+ {D_STR_W_LEN ("7F"), 2, 127}, /* 0x7F, SCHAR_MAX */
+ {D_STR_W_LEN ("7f"), 2, 127}, /* 0x7F, SCHAR_MAX */
+ {D_STR_W_LEN ("80"), 2, 128}, /* 0x80, SCHAR_MAX+1 */
+ {D_STR_W_LEN ("fF"), 2, 255}, /* 0xFF, UCHAR_MAX */
+ {D_STR_W_LEN ("Ff"), 2, 255}, /* 0xFF, UCHAR_MAX */
+ {D_STR_W_LEN ("FF"), 2, 255}, /* 0xFF, UCHAR_MAX */
+ {D_STR_W_LEN ("ff"), 2, 255}, /* 0xFF, UCHAR_MAX */
+ {D_STR_W_LEN ("100"), 3, 256}, /* 0x100, UCHAR_MAX+1 */
+ {D_STR_W_LEN ("7fff"), 4, 32767}, /* 0x7FFF, INT16_MAX */
+ {D_STR_W_LEN ("7FFF"), 4, 32767}, /* 0x7FFF, INT16_MAX */
+ {D_STR_W_LEN ("7Fff"), 4, 32767}, /* 0x7FFF, INT16_MAX */
+ {D_STR_W_LEN ("8000"), 4, 32768}, /* 0x8000, INT16_MAX+1 */
+ {D_STR_W_LEN ("ffff"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
+ {D_STR_W_LEN ("FFFF"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
+ {D_STR_W_LEN ("FffF"), 4, 65535}, /* 0xFFFF, UINT16_MAX */
+ {D_STR_W_LEN ("10000"), 5, 65536}, /* 0x10000, UINT16_MAX+1 */
+ {D_STR_W_LEN ("7FFFFFFF"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
+ {D_STR_W_LEN ("7fffffff"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
+ {D_STR_W_LEN ("7FFffFff"), 8, 2147483647}, /* 0x7FFFFFFF, INT32_MAX */
+ {D_STR_W_LEN ("80000000"), 8, UINT64_C (2147483648)}, /* 0x80000000, INT32_MAX+1 */
+ {D_STR_W_LEN ("FFFFFFFF"), 8, UINT64_C (4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
+ {D_STR_W_LEN ("ffffffff"), 8, UINT64_C (4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
+ {D_STR_W_LEN ("FfFfFfFf"), 8, UINT64_C (4294967295)}, /* 0xFFFFFFFF, UINT32_MAX */
+ {D_STR_W_LEN ("100000000"), 9, UINT64_C (4294967296)}, /* 0x100000000, UINT32_MAX+1 */
+ {D_STR_W_LEN ("7fffffffffffffff"), 16, UINT64_C (9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
+ {D_STR_W_LEN ("7FFFFFFFFFFFFFFF"), 16, UINT64_C (9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
+ {D_STR_W_LEN ("7FfffFFFFffFFffF"), 16, UINT64_C (9223372036854775807)}, /* 0x7FFFFFFFFFFFFFFF, INT64_MAX */
+ {D_STR_W_LEN ("8000000000000000"), 16, UINT64_C (9223372036854775808)}, /* 0x8000000000000000, INT64_MAX+1 */
+ {D_STR_W_LEN ("ffffffffffffffff"), 16, UINT64_C (18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
+ {D_STR_W_LEN ("FFFFFFFFFFFFFFFF"), 16, UINT64_C (18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
+ {D_STR_W_LEN ("FffFffFFffFFfFFF"), 16, UINT64_C (18446744073709551615)}, /* 0xFFFFFFFFFFFFFFFF, UINT64_MAX */
+
+ /* random numbers */
+ {D_STR_W_LEN ("10186753"), 8, 0x10186753},
+ {D_STR_W_LEN ("144402566"), 9, 0x144402566},
+ {D_STR_W_LEN ("151903144"), 9, 0x151903144},
+ {D_STR_W_LEN ("139264621"), 9, 0x139264621},
+ {D_STR_W_LEN ("730348"), 6, 0x730348},
+ {D_STR_W_LEN ("21584377"), 8, 0x21584377},
+ {D_STR_W_LEN ("709"), 3, 0x709},
+ {D_STR_W_LEN ("54"), 2, 0x54},
+ {D_STR_W_LEN ("8452"), 4, 0x8452},
+ {D_STR_W_LEN ("22353EC6"), 8, 0x22353EC6},
+ {D_STR_W_LEN ("307F1655"), 8, 0x307F1655},
+ {D_STR_W_LEN ("1FCB7226"), 8, 0x1FCB7226},
+ {D_STR_W_LEN ("82480560"), 8, 0x82480560},
+ {D_STR_W_LEN ("7386D95"), 7, 0x7386D95},
+ {D_STR_W_LEN ("EC3AB"), 5, 0xEC3AB},
+ {D_STR_W_LEN ("6DD05"), 5, 0x6DD05},
+ {D_STR_W_LEN ("C5DF"), 4, 0xC5DF},
+ {D_STR_W_LEN ("6CE"), 3, 0x6CE},
+ {D_STR_W_LEN ("CE6"), 3, 0xCE6},
+ {D_STR_W_LEN ("ce6"), 3, 0xCE6},
+ {D_STR_W_LEN ("F27"), 3, 0xF27},
+ {D_STR_W_LEN ("8497D54277D7E1"), 14, UINT64_C (37321639124785121)},
+ {D_STR_W_LEN ("8497d54277d7e1"), 14, UINT64_C (37321639124785121)},
+ {D_STR_W_LEN ("8497d54277d7E1"), 14, UINT64_C (37321639124785121)},
+ {D_STR_W_LEN ("8C8112D0A06"), 11, UINT64_C (9655374645766)},
+ {D_STR_W_LEN ("8c8112d0a06"), 11, UINT64_C (9655374645766)},
+ {D_STR_W_LEN ("8c8112d0A06"), 11, UINT64_C (9655374645766)},
+ {D_STR_W_LEN ("1774509875001362"), 16, UINT64_C (1690064375898968930)},
+ {D_STR_W_LEN ("0678687876998000"), 16, UINT64_C (466237428027981824)},
+
+ /* non-digit suffixes */
+ {D_STR_W_LEN ("1234oa"), 4, 0x1234},
+ {D_STR_W_LEN ("20h"), 2, 0x20},
+ {D_STR_W_LEN ("2CH"), 2, 0x2C},
+ {D_STR_W_LEN ("2ch"), 2, 0x2C},
+ {D_STR_W_LEN ("0x1F"), 1, 0x0}, /* not to be interpreted as hex prefix! */
+ {D_STR_W_LEN ("0564`~}"), 4, 0x564},
+ {D_STR_W_LEN ("0A64`~}"), 4, 0xA64},
+ {D_STR_W_LEN ("056c`~}"), 4, 0X56C},
+ {D_STR_W_LEN ("7240146.724"), 7, 0x7240146},
+ {D_STR_W_LEN ("7E4c1AB.724"), 7, 0X7E4C1AB},
+ {D_STR_W_LEN ("F24B1B6.724"), 7, 0xF24B1B6},
+ {D_STR_W_LEN ("2,9"), 1, 0x2},
+ {D_STR_W_LEN ("a,9"), 1, 0xA},
+ {D_STR_W_LEN ("200+1"), 3, 0x200},
+ {D_STR_W_LEN ("2cc+1"), 3, 0x2CC},
+ {D_STR_W_LEN ("2cC+1"), 3, 0x2CC},
+ {D_STR_W_LEN ("27416997! And the not too long string."), 8, 0x27416997},
+ {D_STR_W_LEN ("27555416997! And the not too long string."), 11,
+ 0x27555416997},
+ {D_STR_W_LEN ("416997And the not too long string."), 7, 0x416997A},
+ {D_STR_W_LEN ("0F4C3Dabstract addition to make string even longer"), 8,
+ 0xF4C3DAB}
};
/* hex strings that should overflow uint64_t */
const struct str_with_len strx_ovflw[] = {
- D_STR_W_LEN("10000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("10000000000000001"),
- D_STR_W_LEN("10000000000000002"),
- D_STR_W_LEN("1000000000000000A"),
- D_STR_W_LEN("11000000000000000"),
- D_STR_W_LEN("010000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("000010000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("20000000000000000000"),
- D_STR_W_LEN("020000000000000000000"),
- D_STR_W_LEN("0020000000000000000000"),
- D_STR_W_LEN("20000000000000000"),
- D_STR_W_LEN("A0000000000000000"),
- D_STR_W_LEN("F0000000000000000"),
- D_STR_W_LEN("a0000000000000000"),
- D_STR_W_LEN("11111111111111111"),
- D_STR_W_LEN("CcCcCCccCCccCCccC"),
- D_STR_W_LEN("f0000000000000000"),
- D_STR_W_LEN("100000000000000000000"),
- D_STR_W_LEN("434532891232591226417"),
- D_STR_W_LEN("10000000000000000a"),
- D_STR_W_LEN("10000000000000000E"),
- D_STR_W_LEN("100000000000000000 and nothing"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("100000000000000000xx"), /* 0x10000000000000000, UINT64_MAX+1 */
- D_STR_W_LEN("99999999999999999999"),
- D_STR_W_LEN("18446744073709551616abcd"),
- D_STR_W_LEN("20000000000000000000 suffix"),
- D_STR_W_LEN("020000000000000000000x")
+ D_STR_W_LEN ("10000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("10000000000000001"),
+ D_STR_W_LEN ("10000000000000002"),
+ D_STR_W_LEN ("1000000000000000A"),
+ D_STR_W_LEN ("11000000000000000"),
+ D_STR_W_LEN ("010000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("000010000000000000000"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("20000000000000000000"),
+ D_STR_W_LEN ("020000000000000000000"),
+ D_STR_W_LEN ("0020000000000000000000"),
+ D_STR_W_LEN ("20000000000000000"),
+ D_STR_W_LEN ("A0000000000000000"),
+ D_STR_W_LEN ("F0000000000000000"),
+ D_STR_W_LEN ("a0000000000000000"),
+ D_STR_W_LEN ("11111111111111111"),
+ D_STR_W_LEN ("CcCcCCccCCccCCccC"),
+ D_STR_W_LEN ("f0000000000000000"),
+ D_STR_W_LEN ("100000000000000000000"),
+ D_STR_W_LEN ("434532891232591226417"),
+ D_STR_W_LEN ("10000000000000000a"),
+ D_STR_W_LEN ("10000000000000000E"),
+ D_STR_W_LEN ("100000000000000000 and nothing"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("100000000000000000xx"), /* 0x10000000000000000, UINT64_MAX+1 */
+ D_STR_W_LEN ("99999999999999999999"),
+ D_STR_W_LEN ("18446744073709551616abcd"),
+ D_STR_W_LEN ("20000000000000000000 suffix"),
+ D_STR_W_LEN ("020000000000000000000x")
};
-int check_str_to_uint64_valid(void)
+int
+check_str_to_uint64_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(dstrs_w_values) / sizeof(dstrs_w_values[0]);
+ static const size_t n_checks = sizeof(dstrs_w_values)
+ / sizeof(dstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint64_t rv;
- size_t rs;
- const struct str_with_value * const t = dstrs_w_values + i;
-
- if (c_failed[i])
- continue; /* skip already failed checks */
+ memset (c_failed, 0, sizeof(c_failed));
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: dstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- rv = 9435223; /* some random value */
- rs = MHD_str_to_uint64_(t->str.str, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") returned %" PRIuPTR ", while expecting %d."
- " Locale: %s\n", n_prnt(t->str.str), rv, (intptr_t)rs, (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") converted string to value %" PRIu64 ","
- " while expecting result %" PRIu64 ". Locale: %s\n", n_prnt(t->str.str), rv, rv,
- t->val, get_current_locale_str());
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") == %" PRIuPTR "\n",
- n_prnt(t->str.str), rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint64_t rv;
+ size_t rs;
+ const struct str_with_value *const t = dstrs_w_values + i;
+
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: dstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ rv = 9435223; /* some random value */
+ rs = MHD_str_to_uint64_ (t->str.str, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") returned %"
+ PRIuPTR
+ ", while expecting %d."
+ " Locale: %s\n", n_prnt (t->str.str), rv, (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64
+ ") converted string to value %"
+ PRIu64 ","
+ " while expecting result %" PRIu64 ". Locale: %s\n", n_prnt (
+ t->str.str), rv, rv,
+ t->val, get_current_locale_str ());
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") == %" PRIuPTR "\n",
+ n_prnt (t->str.str), rv, rs);
}
+ }
return t_failed;
}
-int check_str_to_uint64_all_chars(void)
+int
+check_str_to_uint64_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint64_t rnd_val = 24941852;
- size_t rs;
- if (c >= '0' && c <= '9')
- continue; /* skip digits */
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint64_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_str_to_uint64_(test_str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(test_str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: %" PRIu64 ", after call %" PRIu64 "). Locale: %s\n",
- n_prnt(test_str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint64_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint64_t rnd_val = 24941852;
+ size_t rs;
+ if ((c >= '0') && (c <= '9') )
+ continue; /* skip digits */
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint64_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_str_to_uint64_ (test_str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64
+ ") returned %" PRIuPTR
+ ", while expecting zero."
+ " Locale: %s\n", n_prnt (test_str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: %" PRIu64 ", after call %" PRIu64
+ "). Locale: %s\n",
+ n_prnt (test_str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_str_to_uint64_overflow(void)
+int
+check_str_to_uint64_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_ovflw) / sizeof(str_ovflw[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_ovflw + i;
- static const uint64_t rnd_val = 2;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_ovflw + i;
+ static const uint64_t rnd_val = 2;
+ uint64_t test_val;
- rs = MHD_str_to_uint64_(t->str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(t->str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: %" PRIu64 ", after call %" PRIu64 "). Locale: %s\n",
- n_prnt(t->str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(t->str));
- }
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_str_to_uint64_ (t->str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64
+ ") returned %" PRIuPTR
+ ", while expecting zero."
+ " Locale: %s\n", n_prnt (t->str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: %" PRIu64 ", after call %" PRIu64
+ "). Locale: %s\n",
+ n_prnt (t->str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (t->str));
}
+ }
return t_failed;
}
-int check_str_to_uint64_no_val(void)
+int
+check_str_to_uint64_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint64_t rnd_val = 74218431;
- uint64_t test_val;
-
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint64_t rnd_val = 74218431;
+ uint64_t test_val;
- rs = MHD_str_to_uint64_(t->str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(t->str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: %" PRIu64 ", after call %" PRIu64 "). Locale: %s\n",
- n_prnt(t->str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(t->str));
- }
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_str_to_uint64_ (t->str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", ->%" PRIu64
+ ") returned %" PRIuPTR
+ ", while expecting zero."
+ " Locale: %s\n", n_prnt (t->str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: %" PRIu64 ", after call %" PRIu64
+ "). Locale: %s\n",
+ n_prnt (t->str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (t->str));
}
+ }
return t_failed;
}
-int check_str_to_uint64_n_valid(void)
+int
+check_str_to_uint64_n_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(dstrs_w_values) / sizeof(dstrs_w_values[0]);
+ static const size_t n_checks = sizeof(dstrs_w_values)
+ / sizeof(dstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint64_t rv = 1235572; /* some random value */
- size_t rs = 0;
- size_t len;
- const struct str_with_value * const t = dstrs_w_values + i;
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: dstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- for (len = t->num_of_digt; len <= t->str.len + 1 && !c_failed[i]; len++)
- {
- rs = MHD_str_to_uint64_n_(t->str.str, len, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%" PRIu64 ")"
- " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
- n_prnt(t->str.str), (intptr_t)len, rv, (intptr_t)rs,
- (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%" PRIu64 ")"
- " converted string to value %" PRIu64 ", while expecting result %" PRIu64
- ". Locale: %s\n", n_prnt(t->str.str), (intptr_t)len, rv, rv,
- t->val, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", ->%" PRIu64 ")"
- " == %" PRIuPTR "\n", n_prnt(t->str.str), (intptr_t)t->num_of_digt,
- (intptr_t)t->str.len + 1, rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint64_t rv = 1235572; /* some random value */
+ size_t rs = 0;
+ size_t len;
+ const struct str_with_value *const t = dstrs_w_values + i;
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: dstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ for (len = t->num_of_digt; len <= t->str.len + 1 && ! c_failed[i]; len++)
+ {
+ rs = MHD_str_to_uint64_n_ (t->str.str, len, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
+ n_prnt (t->str.str), (intptr_t) len, rv, (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " converted string to value %" PRIu64
+ ", while expecting result %" PRIu64
+ ". Locale: %s\n", n_prnt (t->str.str), (intptr_t) len, rv,
+ rv,
+ t->val, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " == %" PRIuPTR "\n", n_prnt (t->str.str),
+ (intptr_t) t->num_of_digt,
+ (intptr_t) t->str.len + 1, rv, rs);
}
+ }
return t_failed;
}
-int check_str_to_uint64_n_all_chars(void)
+int
+check_str_to_uint64_n_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint64_t rnd_val = 98372558;
- size_t rs;
- size_t len;
-
- if (c >= '0' && c <= '9')
- continue; /* skip digits */
-
- for (len = 0; len <= 5; len++)
- {
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint64_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_str_to_uint64_n_(test_str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%" PRIu64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: %" PRIu64 ", after call %" PRIu64 ")."
- " Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, test_val, rv, get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_str_to_uint64_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint64_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint64_t rnd_val = 98372558;
+ size_t rs;
+ size_t len;
+
+ if ((c >= '0') && (c <= '9') )
+ continue; /* skip digits */
+
+ for (len = 0; len <= 5; len++)
+ {
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint64_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_str_to_uint64_n_ (test_str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: %" PRIu64
+ ", after call %" PRIu64 ")."
+ " Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_str_to_uint64_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_str_to_uint64_n_overflow(void)
+int
+check_str_to_uint64_n_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_ovflw) / sizeof(str_ovflw[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_ovflw + i;
- static const uint64_t rnd_val = 3;
- size_t len;
-
- for (len = t->len; len <= t->len + 1; len++)
- {
- uint64_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
-
- rs = MHD_str_to_uint64_n_(t->str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%" PRIu64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(t->str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: %" PRIu64 ", after call %" PRIu64 ")."
- " Locale: %s\n", n_prnt(t->str), (uintptr_t)len, test_val, rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(t->str), (uintptr_t)t->len,
- (uintptr_t)t->len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_ovflw + i;
+ static const uint64_t rnd_val = 3;
+ size_t len;
+
+ for (len = t->len; len <= t->len + 1; len++)
+ {
+ uint64_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_str_to_uint64_n_ (t->str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (t->str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: %" PRIu64
+ ", after call %" PRIu64 ")."
+ " Locale: %s\n", n_prnt (t->str), (uintptr_t) len,
+ test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (t->str),
+ (uintptr_t) t->len,
+ (uintptr_t) t->len + 1);
}
+ }
return t_failed;
}
-int check_str_to_uint64_n_no_val(void)
+int
+check_str_to_uint64_n_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint64_t rnd_val = 43255654342;
- size_t len;
-
- for (len = 0; len <= t->len + 1; len++)
- {
- uint64_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
-
- rs = MHD_str_to_uint64_n_(t->str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%" PRIu64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(t->str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: %" PRIu64 ", after call %" PRIu64 ")."
- " Locale: %s\n", n_prnt(t->str), (uintptr_t)len, test_val, rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_str_to_uint64_n_(\"%s\", 0..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(t->str),
- (uintptr_t)t->len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint64_t rnd_val = 43255654342;
+ size_t len;
+
+ for (len = 0; len <= t->len + 1; len++)
+ {
+ uint64_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_str_to_uint64_n_ (t->str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR ", ->%"
+ PRIu64 ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (t->str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_str_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: %" PRIu64
+ ", after call %" PRIu64 ")."
+ " Locale: %s\n", n_prnt (t->str), (uintptr_t) len,
+ test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_str_to_uint64_n_(\"%s\", 0..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (t->str),
+ (uintptr_t) t->len + 1);
}
+ }
return t_failed;
}
-int check_strx_to_uint32_valid(void)
+int
+check_strx_to_uint32_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
+ static const size_t n_checks = sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint32_t rv;
- size_t rs;
- const struct str_with_value * const t = xdstrs_w_values + i;
-
- if (t->val > UINT32_MAX)
- continue; /* number is too high for this function */
-
- if (c_failed[i])
- continue; /* skip already failed checks */
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- rv = 1458532; /* some random value */
- rs = MHD_strx_to_uint32_(t->str.str, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting %d."
- " Locale: %s\n", n_prnt(t->str.str), (uint64_t)rv, (intptr_t)rs, (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") converted string to value 0x%" PRIX64 ","
- " while expecting result 0x%" PRIX64 ". Locale: %s\n", n_prnt(t->str.str), (uint64_t)rv, (uint64_t)rv,
- t->val, get_current_locale_str());
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") == %" PRIuPTR "\n",
- n_prnt(t->str.str), (uint64_t)rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint32_t rv;
+ size_t rs;
+ const struct str_with_value *const t = xdstrs_w_values + i;
+
+ if (t->val > UINT32_MAX)
+ continue; /* number is too high for this function */
+
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ rv = 1458532; /* some random value */
+ rs = MHD_strx_to_uint32_ (t->str.str, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting %d."
+ " Locale: %s\n", n_prnt (t->str.str), (uint64_t) rv,
+ (intptr_t) rs, (int) t->num_of_digt,
+ get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64
+ ") converted string to value 0x%"
+ PRIX64 ","
+ " while expecting result 0x%" PRIX64 ". Locale: %s\n", n_prnt (
+ t->str.str), (uint64_t) rv, (uint64_t) rv,
+ t->val, get_current_locale_str ());
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") == %" PRIuPTR
+ "\n",
+ n_prnt (t->str.str), (uint64_t) rv, rs);
}
+ }
return t_failed;
}
-int check_strx_to_uint32_all_chars(void)
+int
+check_strx_to_uint32_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint32_t test_val;
-
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint32_t rnd_val = 234234;
- size_t rs;
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||(c >= 'a' && c <= 'f'))
- continue; /* skip xdigits */
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint32_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_strx_to_uint32_(test_str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(test_str), (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(test_str), (uint64_t)test_val, (uint64_t)rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint32_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint32_t rnd_val = 234234;
+ size_t rs;
+ if (((c >= '0') && (c <= '9') ) || ((c >= 'A') && (c <= 'F') ) || ((c >=
+ 'a')
+ &&
+ (c <=
+ 'f') ))
+ continue; /* skip xdigits */
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint32_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_strx_to_uint32_ (test_str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (test_str), (uint64_t) rv,
+ (uintptr_t) rs, get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (test_str), (uint64_t) test_val, (uint64_t) rv,
+ get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_strx_to_uint32_overflow(void)
+int
+check_strx_to_uint32_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks1 = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]);
- static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]) +
- sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
+ static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0])
+ + sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
{
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- static const uint32_t rnd_val = 74218431;
- uint32_t test_val;
- const char * str;
- if (i < n_checks1)
- {
- const struct str_with_len * const t = strx_ovflw + i;
- str = t->str;
- }
- else
- {
- const struct str_with_value * const t = xdstrs_w_values + (i - n_checks1);
- if (t->val <= UINT32_MAX)
- continue; /* check only strings that should overflow uint32_t */
- str = t->str.str;
- }
-
-
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint32_t rv = test_val;
-
- rs = MHD_strx_to_uint32_(str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(str), (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(str), (uint64_t)test_val, (uint64_t)rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(str));
- }
+ size_t rs;
+ static const uint32_t rnd_val = 74218431;
+ uint32_t test_val;
+ const char *str;
+ if (i < n_checks1)
+ {
+ const struct str_with_len *const t = strx_ovflw + i;
+ str = t->str;
+ }
+ else
+ {
+ const struct str_with_value *const t = xdstrs_w_values + (i
+ - n_checks1);
+ if (t->val <= UINT32_MAX)
+ continue; /* check only strings that should overflow uint32_t */
+ str = t->str.str;
+ }
+
+
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint32_t rv = test_val;
+
+ rs = MHD_strx_to_uint32_ (str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (str), (uint64_t) rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (str), (uint64_t) test_val, (uint64_t) rv,
+ get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (str));
}
+ }
return t_failed;
}
-int check_strx_to_uint32_no_val(void)
+int
+check_strx_to_uint32_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint32_t rnd_val = 74218431;
- uint32_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint32_t rv = test_val;
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint32_t rnd_val = 74218431;
+ uint32_t test_val;
- rs = MHD_strx_to_uint32_(t->str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(t->str), (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(t->str), (uint64_t)test_val, (uint64_t)rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(t->str));
- }
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint32_t rv = test_val;
+
+ rs = MHD_strx_to_uint32_ (t->str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (t->str), (uint64_t) rv,
+ (uintptr_t) rs, get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (t->str), (uint64_t) test_val, (uint64_t) rv,
+ get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (t->str));
}
+ }
return t_failed;
}
-int check_strx_to_uint32_n_valid(void)
+int
+check_strx_to_uint32_n_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
+ static const size_t n_checks = sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint32_t rv = 2352932; /* some random value */
- size_t rs = 0;
- size_t len;
- const struct str_with_value * const t = xdstrs_w_values + i;
-
- if (t->val > UINT32_MAX)
- continue; /* number is too high for this function */
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- for (len = t->num_of_digt; len <= t->str.len + 1 && !c_failed[i]; len++)
- {
- rs = MHD_strx_to_uint32_n_(t->str.str, len, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
- n_prnt(t->str.str), (intptr_t)len, (uint64_t)rv, (intptr_t)rs,
- (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " converted string to value 0x%" PRIX64 ", while expecting result 0x%" PRIX64
- ". Locale: %s\n", n_prnt(t->str.str), (intptr_t)len, (uint64_t)rv, (uint64_t)rv,
- t->val, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", ->0x%" PRIX64 ")"
- " == %" PRIuPTR "\n", n_prnt(t->str.str), (intptr_t)t->num_of_digt,
- (intptr_t)t->str.len + 1, (uint64_t)rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint32_t rv = 2352932; /* some random value */
+ size_t rs = 0;
+ size_t len;
+ const struct str_with_value *const t = xdstrs_w_values + i;
+
+ if (t->val > UINT32_MAX)
+ continue; /* number is too high for this function */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ for (len = t->num_of_digt; len <= t->str.len + 1 && ! c_failed[i]; len++)
+ {
+ rs = MHD_strx_to_uint32_n_ (t->str.str, len, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64 ")"
+ " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
+ n_prnt (t->str.str), (intptr_t) len, (uint64_t) rv,
+ (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64 ")"
+ " converted string to value 0x%" PRIX64
+ ", while expecting result 0x%" PRIX64
+ ". Locale: %s\n", n_prnt (t->str.str), (intptr_t) len,
+ (uint64_t) rv, (uint64_t) rv,
+ t->val, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR
+ ", ->0x%"
+ PRIX64 ")"
+ " == %" PRIuPTR "\n", n_prnt (t->str.str),
+ (intptr_t) t->num_of_digt,
+ (intptr_t) t->str.len + 1, (uint64_t) rv, rs);
}
+ }
return t_failed;
}
-int check_strx_to_uint32_n_all_chars(void)
+int
+check_strx_to_uint32_n_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint32_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint32_t rnd_val = 98372558;
- size_t rs;
- size_t len;
-
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
- continue; /* skip xdigits */
-
- for (len = 0; len <= 5; len++)
- {
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint32_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_strx_to_uint32_n_(test_str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, (uint64_t)test_val, (uint64_t)rv, get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_strx_to_uint32_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint32_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint32_t rnd_val = 98372558;
+ size_t rs;
+ size_t len;
+
+ if (((c >= '0') && (c <= '9') ) || ((c >= 'A') && (c <= 'F') ) || ((c >=
+ 'a')
+ &&
+ (c <=
+ 'f') ))
+ continue; /* skip xdigits */
+
+ for (len = 0; len <= 5; len++)
+ {
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint32_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_strx_to_uint32_n_ (test_str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, (uint64_t) rv,
+ (uintptr_t) rs, get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, (uint64_t) test_val,
+ (uint64_t) rv, get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_strx_to_uint32_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_strx_to_uint32_n_overflow(void)
+int
+check_strx_to_uint32_n_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks1 = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]);
- static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]) +
- sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
- int c_failed[n_checks];
-
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- static const uint32_t rnd_val = 4;
- size_t len;
- const char * str;
- size_t min_len, max_len;
- if (i < n_checks1)
- {
- const struct str_with_len * const t = strx_ovflw + i;
- str = t->str;
- min_len = t->len;
- max_len = t->len + 1;
- }
- else
- {
- const struct str_with_value * const t = xdstrs_w_values + (i - n_checks1);
- if (t->val <= UINT32_MAX)
- continue; /* check only strings that should overflow uint32_t */
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) (i - n_checks1), (unsigned int) t->num_of_digt,
- (unsigned int) t->str.len);
- return -1;
- }
- str = t->str.str;
- min_len = t->num_of_digt;
- max_len = t->str.len + 1;
- }
-
- for (len = min_len; len <= max_len; len++)
- {
- uint32_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint32_t rv = test_val;
-
- rs = MHD_strx_to_uint32_n_(str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(str), (uintptr_t)len, (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n", n_prnt(str), (uintptr_t)len, (uint64_t)test_val, (uint64_t)rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(str), (uintptr_t)min_len,
- (uintptr_t)max_len);
- }
+ static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0])
+ + sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
+ int c_failed[n_checks];
+
+ memset (c_failed, 0, sizeof(c_failed));
+
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ static const uint32_t rnd_val = 4;
+ size_t len;
+ const char *str;
+ size_t min_len, max_len;
+ if (i < n_checks1)
+ {
+ const struct str_with_len *const t = strx_ovflw + i;
+ str = t->str;
+ min_len = t->len;
+ max_len = t->len + 1;
+ }
+ else
+ {
+ const struct str_with_value *const t = xdstrs_w_values + (i
+ - n_checks1);
+ if (t->val <= UINT32_MAX)
+ continue; /* check only strings that should overflow uint32_t */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) (i - n_checks1), (unsigned
+ int) t->num_of_digt,
+ (unsigned int) t->str.len);
+ return -1;
+ }
+ str = t->str.str;
+ min_len = t->num_of_digt;
+ max_len = t->str.len + 1;
+ }
+
+ for (len = min_len; len <= max_len; len++)
+ {
+ uint32_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint32_t rv = test_val;
+
+ rs = MHD_strx_to_uint32_n_ (str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (str), (uintptr_t) len, (uint64_t) rv,
+ (uintptr_t) rs, get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n", n_prnt (str), (uintptr_t) len,
+ (uint64_t) test_val, (uint64_t) rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (str),
+ (uintptr_t) min_len,
+ (uintptr_t) max_len);
}
+ }
return t_failed;
}
-int check_strx_to_uint32_n_no_val(void)
+int
+check_strx_to_uint32_n_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint32_t rnd_val = 3214314212L;
- size_t len;
-
- for (len = 0; len <= t->len + 1; len++)
- {
- uint32_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint32_t rv = test_val;
-
- rs = MHD_strx_to_uint32_n_(t->str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(t->str), (uintptr_t)len, (uint64_t)rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n", n_prnt(t->str), (uintptr_t)len, (uint64_t)test_val, (uint64_t)rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint32_n_(\"%s\", 0..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(t->str),
- (uintptr_t)t->len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint32_t rnd_val = 3214314212UL;
+ size_t len;
+
+ for (len = 0; len <= t->len + 1; len++)
+ {
+ uint32_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint32_t rv = test_val;
+
+ rs = MHD_strx_to_uint32_n_ (t->str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (t->str), (uintptr_t) len, (uint64_t) rv,
+ (uintptr_t) rs, get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint32_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n", n_prnt (t->str), (uintptr_t) len,
+ (uint64_t) test_val, (uint64_t) rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint32_n_(\"%s\", 0..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (t->str),
+ (uintptr_t) t->len + 1);
}
+ }
return t_failed;
}
-int check_strx_to_uint64_valid(void)
+int
+check_strx_to_uint64_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
+ static const size_t n_checks = sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint64_t rv;
- size_t rs;
- const struct str_with_value * const t = xdstrs_w_values + i;
-
- if (c_failed[i])
- continue; /* skip already failed checks */
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- rv = 1458532; /* some random value */
- rs = MHD_strx_to_uint64_(t->str.str, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting %d."
- " Locale: %s\n", n_prnt(t->str.str), rv, (intptr_t)rs, (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") converted string to value 0x%" PRIX64 ","
- " while expecting result 0x%" PRIX64 ". Locale: %s\n", n_prnt(t->str.str), rv, rv,
- t->val, get_current_locale_str());
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") == %" PRIuPTR "\n",
- n_prnt(t->str.str), rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint64_t rv;
+ size_t rs;
+ const struct str_with_value *const t = xdstrs_w_values + i;
+
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ rv = 1458532; /* some random value */
+ rs = MHD_strx_to_uint64_ (t->str.str, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting %d."
+ " Locale: %s\n", n_prnt (t->str.str), rv, (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64
+ ") converted string to value 0x%"
+ PRIX64 ","
+ " while expecting result 0x%" PRIX64 ". Locale: %s\n", n_prnt (
+ t->str.str), rv, rv,
+ t->val, get_current_locale_str ());
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") == %" PRIuPTR
+ "\n",
+ n_prnt (t->str.str), rv, rs);
}
+ }
return t_failed;
}
-int check_strx_to_uint64_all_chars(void)
+int
+check_strx_to_uint64_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint64_t rnd_val = 234234;
- size_t rs;
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
- continue; /* skip xdigits */
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint64_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_strx_to_uint64_(test_str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(test_str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(test_str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint64_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint64_t rnd_val = 234234;
+ size_t rs;
+ if (((c >= '0') && (c <= '9') ) || ((c >= 'A') && (c <= 'F') ) || ((c >=
+ 'a')
+ &&
+ (c <=
+ 'f') ))
+ continue; /* skip xdigits */
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint64_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_strx_to_uint64_ (test_str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (test_str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (test_str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_strx_to_uint64_overflow(void)
+int
+check_strx_to_uint64_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = strx_ovflw + i;
- static const uint64_t rnd_val = 74218431;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = strx_ovflw + i;
+ static const uint64_t rnd_val = 74218431;
+ uint64_t test_val;
- rs = MHD_strx_to_uint64_(t->str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(t->str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(t->str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(t->str));
- }
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_strx_to_uint64_ (t->str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (t->str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (t->str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (t->str));
}
+ }
return t_failed;
}
-int check_strx_to_uint64_no_val(void)
+int
+check_strx_to_uint64_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint64_t rnd_val = 74218431;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint64_t rnd_val = 74218431;
+ uint64_t test_val;
- rs = MHD_strx_to_uint64_(t->str, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64 ") returned %" PRIuPTR ", while expecting zero."
- " Locale: %s\n", n_prnt(t->str), rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
- " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 "). Locale: %s\n",
- n_prnt(t->str), test_val, rv, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(t->str));
- }
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_strx_to_uint64_ (t->str, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", ->0x%" PRIX64
+ ") returned %"
+ PRIuPTR ", while expecting zero."
+ " Locale: %s\n", n_prnt (t->str), rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_(\"%s\", &ret_val) modified value of ret_val"
+ " (before call: 0x%" PRIX64 ", after call 0x%" PRIX64
+ "). Locale: %s\n",
+ n_prnt (t->str), test_val, rv, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_(\"%s\", &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (t->str));
}
+ }
return t_failed;
}
-int check_strx_to_uint64_n_valid(void)
+int
+check_strx_to_uint64_n_valid (void)
{
size_t t_failed = 0;
size_t i, j;
- static const size_t n_checks = sizeof(xdstrs_w_values) / sizeof(xdstrs_w_values[0]);
+ static const size_t n_checks = sizeof(xdstrs_w_values)
+ / sizeof(xdstrs_w_values[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- uint64_t rv = 2352932; /* some random value */
- size_t rs = 0;
- size_t len;
- const struct str_with_value * const t = xdstrs_w_values + i;
-
- if (t->str.len < t->num_of_digt)
- {
- fprintf(stderr, "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
- " to be less or equal to str.len (%u).\n",
- (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned int) t->str.len);
- return -1;
- }
- for (len = t->num_of_digt; len <= t->str.len + 1 && !c_failed[i]; len++)
- {
- rs = MHD_strx_to_uint64_n_(t->str.str, len, &rv);
- if (rs != t->num_of_digt)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
- n_prnt(t->str.str), (intptr_t)len, rv, (intptr_t)rs,
- (int)t->num_of_digt, get_current_locale_str());
- }
- if (rv != t->val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " converted string to value 0x%" PRIX64 ", while expecting result 0x%" PRIX64
- ". Locale: %s\n", n_prnt(t->str.str), (intptr_t)len, rv, rv,
- t->val, get_current_locale_str());
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", ->0x%" PRIX64 ")"
- " == %" PRIuPTR "\n", n_prnt(t->str.str), (intptr_t)t->num_of_digt,
- (intptr_t)t->str.len + 1, rv, rs);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ uint64_t rv = 2352932; /* some random value */
+ size_t rs = 0;
+ size_t len;
+ const struct str_with_value *const t = xdstrs_w_values + i;
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: xdstrs_w_values[%u] has wrong num_of_digt (%u): num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ for (len = t->num_of_digt; len <= t->str.len + 1 && ! c_failed[i]; len++)
+ {
+ rs = MHD_strx_to_uint64_n_ (t->str.str, len, &rv);
+ if (rs != t->num_of_digt)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64 ")"
+ " returned %" PRIuPTR ", while expecting %d. Locale: %s\n",
+ n_prnt (t->str.str), (intptr_t) len, rv, (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ if (rv != t->val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64 ")"
+ " converted string to value 0x%" PRIX64
+ ", while expecting result 0x%" PRIX64
+ ". Locale: %s\n", n_prnt (t->str.str), (intptr_t) len, rv,
+ rv,
+ t->val, get_current_locale_str ());
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR
+ ", ->0x%"
+ PRIX64 ")"
+ " == %" PRIuPTR "\n", n_prnt (t->str.str),
+ (intptr_t) t->num_of_digt,
+ (intptr_t) t->str.len + 1, rv, rs);
}
+ }
return t_failed;
}
-int check_strx_to_uint64_n_all_chars(void)
+int
+check_strx_to_uint64_n_all_chars (void)
{
static const size_t n_checks = 256; /* from 0 to 255 */
int c_failed[n_checks];
size_t t_failed = 0;
size_t j;
- memset(c_failed, 0, sizeof(c_failed));
-
- for(j = 0; j < locale_name_count; j++)
- {
- unsigned int c;
- uint64_t test_val;
+ memset (c_failed, 0, sizeof(c_failed));
- set_test_locale(j); /* setlocale() can be slow! */
- for(c = 0; c < n_checks; c++)
- {
- static const uint64_t rnd_val = 98372558;
- size_t rs;
- size_t len;
-
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
- continue; /* skip xdigits */
-
- for (len = 0; len <= 5; len++)
- {
- for(test_val = 0; test_val <= rnd_val&& !c_failed[c]; test_val += rnd_val)
- {
- char test_str[] = "0123";
- uint64_t rv = test_val;
-
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
- rs = MHD_strx_to_uint64_n_(test_str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[c] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n",
- n_prnt(test_str), (uintptr_t)len, test_val, rv, get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[c])
- {
- char test_str[] = "0123";
- test_str[0] = (char) (unsigned char)c; /* replace first char with non-digit char */
-
- printf("PASSED: MHD_strx_to_uint64_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
- n_prnt(test_str));
- }
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ unsigned int c;
+ uint64_t test_val;
+
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (c = 0; c < n_checks; c++)
+ {
+ static const uint64_t rnd_val = 98372558;
+ size_t rs;
+ size_t len;
+
+ if (((c >= '0') && (c <= '9') ) || ((c >= 'A') && (c <= 'F') ) || ((c >=
+ 'a')
+ &&
+ (c <=
+ 'f') ))
+ continue; /* skip xdigits */
+
+ for (len = 0; len <= 5; len++)
+ {
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[c]; test_val +=
+ rnd_val)
+ {
+ char test_str[] = "0123";
+ uint64_t rv = test_val;
+
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+ rs = MHD_strx_to_uint64_n_ (test_str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[c] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n",
+ n_prnt (test_str), (uintptr_t) len, test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[c])
+ {
+ char test_str[] = "0123";
+ test_str[0] = (char) (unsigned char) c; /* replace first char with non-digit char */
+
+ printf (
+ "PASSED: MHD_strx_to_uint64_n_(\"%s\", 0..5, &ret_val) == 0, value of ret_val is unmodified\n",
+ n_prnt (test_str));
+ }
}
+ }
return t_failed;
}
-int check_strx_to_uint64_n_overflow(void)
+int
+check_strx_to_uint64_n_overflow (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(strx_ovflw) / sizeof(strx_ovflw[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = strx_ovflw + i;
- static const uint64_t rnd_val = 4;
- size_t len;
-
- for (len = t->len; len <= t->len + 1; len++)
- {
- uint64_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
-
- rs = MHD_strx_to_uint64_n_(t->str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(t->str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n", n_prnt(t->str), (uintptr_t)len, test_val, rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(t->str), (uintptr_t)t->len,
- (uintptr_t)t->len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = strx_ovflw + i;
+ static const uint64_t rnd_val = 4;
+ size_t len;
+
+ for (len = t->len; len <= t->len + 1; len++)
+ {
+ uint64_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_strx_to_uint64_n_ (t->str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (t->str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n", n_prnt (t->str), (uintptr_t) len,
+ test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR "..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (t->str),
+ (uintptr_t) t->len,
+ (uintptr_t) t->len + 1);
}
+ }
return t_failed;
}
-int check_strx_to_uint64_n_no_val(void)
+int
+check_strx_to_uint64_n_no_val (void)
{
size_t t_failed = 0;
size_t i, j;
static const size_t n_checks = sizeof(str_no_num) / sizeof(str_no_num[0]);
int c_failed[n_checks];
- memset(c_failed, 0, sizeof(c_failed));
+ memset (c_failed, 0, sizeof(c_failed));
- for(j = 0; j < locale_name_count; j++)
- {
- set_test_locale(j); /* setlocale() can be slow! */
- for(i = 0; i < n_checks; i++)
- {
- size_t rs;
- const struct str_with_len * const t = str_no_num + i;
- static const uint64_t rnd_val = 3214314212L;
- size_t len;
-
- for (len = 0; len <= t->len + 1; len++)
- {
- uint64_t test_val;
- for(test_val = 0; test_val <= rnd_val && !c_failed[i]; test_val += rnd_val)
- {
- uint64_t rv = test_val;
-
- rs = MHD_strx_to_uint64_n_(t->str, len, &rv);
- if (rs != 0)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%" PRIX64 ")"
- " returned %" PRIuPTR ", while expecting zero. Locale: %s\n",
- n_prnt(t->str), (uintptr_t)len, rv, (uintptr_t)rs, get_current_locale_str());
- }
- else if (rv != test_val)
- {
- t_failed++;
- c_failed[i] = !0;
- fprintf(stderr, "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", &ret_val)"
- " modified value of ret_val (before call: 0x%" PRIX64 ", after call 0x%" PRIX64 ")."
- " Locale: %s\n", n_prnt(t->str), (uintptr_t)len, test_val, rv,
- get_current_locale_str());
- }
- }
- }
- if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
- printf("PASSED: MHD_strx_to_uint64_n_(\"%s\", 0..%" PRIuPTR ", &ret_val) == 0,"
- " value of ret_val is unmodified\n", n_prnt(t->str),
- (uintptr_t)t->len + 1);
- }
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ size_t rs;
+ const struct str_with_len *const t = str_no_num + i;
+ static const uint64_t rnd_val = 3214314212UL;
+ size_t len;
+
+ for (len = 0; len <= t->len + 1; len++)
+ {
+ uint64_t test_val;
+ for (test_val = 0; test_val <= rnd_val && ! c_failed[i]; test_val +=
+ rnd_val)
+ {
+ uint64_t rv = test_val;
+
+ rs = MHD_strx_to_uint64_n_ (t->str, len, &rv);
+ if (rs != 0)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR ", ->0x%"
+ PRIX64
+ ")"
+ " returned %" PRIuPTR
+ ", while expecting zero. Locale: %s\n",
+ n_prnt (t->str), (uintptr_t) len, rv, (uintptr_t) rs,
+ get_current_locale_str ());
+ }
+ else if (rv != test_val)
+ {
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_strx_to_uint64_n_(\"%s\", %" PRIuPTR
+ ", &ret_val)"
+ " modified value of ret_val (before call: 0x%" PRIX64
+ ", after call 0x%" PRIX64 ")."
+ " Locale: %s\n", n_prnt (t->str), (uintptr_t) len,
+ test_val, rv,
+ get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf (
+ "PASSED: MHD_strx_to_uint64_n_(\"%s\", 0..%" PRIuPTR
+ ", &ret_val) == 0,"
+ " value of ret_val is unmodified\n", n_prnt (t->str),
+ (uintptr_t) t->len + 1);
}
+ }
return t_failed;
}
-int run_str_to_X_tests(void)
+int
+run_str_to_X_tests (void)
{
int str_to_uint64_fails = 0;
int str_to_uint64_n_fails = 0;
@@ -2447,406 +2841,492 @@
int strx_to_uint64_n_fails = 0;
int res;
- res = check_str_to_uint64_valid();
+ res = check_str_to_uint64_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_valid().\n");
- return 99;
- }
- str_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_valid().\n");
+ return 99;
}
+ str_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_valid() successfully passed.\n\n");
- res = check_str_to_uint64_all_chars();
+ res = check_str_to_uint64_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_all_chars().\n");
- return 99;
- }
- str_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_all_chars().\n");
+ return 99;
}
+ str_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_all_chars() successfully passed.\n\n");
- res = check_str_to_uint64_overflow();
+ res = check_str_to_uint64_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_overflow().\n");
- return 99;
- }
- str_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_overflow().\n");
+ return 99;
}
+ str_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_overflow() successfully passed.\n\n");
- res = check_str_to_uint64_no_val();
+ res = check_str_to_uint64_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_no_val().\n");
- return 99;
- }
- str_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_no_val().\n");
+ return 99;
}
+ str_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_no_val() successfully passed.\n\n");
if (str_to_uint64_fails)
- fprintf(stderr, "FAILED: function MHD_str_to_uint64_() failed %d time%s.\n\n",
- str_to_uint64_fails, str_to_uint64_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_str_to_uint64_() failed %d time%s.\n\n",
+ str_to_uint64_fails, str_to_uint64_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_str_to_uint64_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_str_to_uint64_() successfully passed all checks.\n\n");
- res = check_str_to_uint64_n_valid();
+ res = check_str_to_uint64_n_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_n_valid().\n");
- return 99;
- }
- str_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_n_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_n_valid().\n");
+ return 99;
}
+ str_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_n_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_n_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_n_valid() successfully passed.\n\n");
- res = check_str_to_uint64_n_all_chars();
+ res = check_str_to_uint64_n_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_n_all_chars().\n");
- return 99;
- }
- str_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_n_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_n_all_chars().\n");
+ return 99;
}
+ str_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_n_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_n_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_n_all_chars() successfully passed.\n\n");
- res = check_str_to_uint64_n_overflow();
+ res = check_str_to_uint64_n_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_n_overflow().\n");
- return 99;
- }
- str_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_n_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_n_overflow().\n");
+ return 99;
}
+ str_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_n_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_n_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_n_overflow() successfully passed.\n\n");
- res = check_str_to_uint64_n_no_val();
+ res = check_str_to_uint64_n_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_str_to_uint64_n_no_val().\n");
- return 99;
- }
- str_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_str_to_uint64_n_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_to_uint64_n_no_val().\n");
+ return 99;
}
+ str_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_str_to_uint64_n_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_str_to_uint64_n_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_str_to_uint64_n_no_val() successfully passed.\n\n");
if (str_to_uint64_n_fails)
- fprintf(stderr, "FAILED: function MHD_str_to_uint64_n_() failed %d time%s.\n\n",
- str_to_uint64_n_fails, str_to_uint64_n_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_str_to_uint64_n_() failed %d time%s.\n\n",
+ str_to_uint64_n_fails, str_to_uint64_n_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_str_to_uint64_n_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_str_to_uint64_n_() successfully passed all checks.\n\n");
- res = check_strx_to_uint32_valid();
+ res = check_strx_to_uint32_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_valid().\n");
- return 99;
- }
- strx_to_uint32_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_valid().\n");
+ return 99;
}
+ strx_to_uint32_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_valid() successfully passed.\n\n");
- res = check_strx_to_uint32_all_chars();
+ res = check_strx_to_uint32_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_all_chars().\n");
- return 99;
- }
- strx_to_uint32_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_all_chars().\n");
+ return 99;
}
+ strx_to_uint32_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_all_chars() successfully passed.\n\n");
- res = check_strx_to_uint32_overflow();
+ res = check_strx_to_uint32_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_overflow().\n");
- return 99;
- }
- strx_to_uint32_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_overflow().\n");
+ return 99;
}
+ strx_to_uint32_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_overflow() successfully passed.\n\n");
- res = check_strx_to_uint32_no_val();
+ res = check_strx_to_uint32_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_no_val().\n");
- return 99;
- }
- strx_to_uint32_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_no_val().\n");
+ return 99;
}
+ strx_to_uint32_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_no_val() successfully passed.\n\n");
if (strx_to_uint32_fails)
- fprintf(stderr, "FAILED: function MHD_strx_to_uint32_() failed %d time%s.\n\n",
- strx_to_uint32_fails, strx_to_uint32_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_strx_to_uint32_() failed %d time%s.\n\n",
+ strx_to_uint32_fails, strx_to_uint32_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_strx_to_uint32_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_strx_to_uint32_() successfully passed all checks.\n\n");
- res = check_strx_to_uint32_n_valid();
+ res = check_strx_to_uint32_n_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_n_valid().\n");
- return 99;
- }
- strx_to_uint32_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_n_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_n_valid().\n");
+ return 99;
}
+ strx_to_uint32_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_n_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_n_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_n_valid() successfully passed.\n\n");
- res = check_strx_to_uint32_n_all_chars();
+ res = check_strx_to_uint32_n_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_n_all_chars().\n");
- return 99;
- }
- strx_to_uint32_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_n_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_n_all_chars().\n");
+ return 99;
}
+ strx_to_uint32_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_n_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_n_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_n_all_chars() successfully passed.\n\n");
- res = check_strx_to_uint32_n_overflow();
+ res = check_strx_to_uint32_n_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_n_overflow().\n");
- return 99;
- }
- strx_to_uint32_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_n_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_n_overflow().\n");
+ return 99;
}
+ strx_to_uint32_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_n_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_n_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_n_overflow() successfully passed.\n\n");
- res = check_strx_to_uint32_n_no_val();
+ res = check_strx_to_uint32_n_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint32_n_no_val().\n");
- return 99;
- }
- strx_to_uint32_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint32_n_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint32_n_no_val().\n");
+ return 99;
}
+ strx_to_uint32_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint32_n_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint32_n_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint32_n_no_val() successfully passed.\n\n");
if (strx_to_uint32_n_fails)
- fprintf(stderr, "FAILED: function MHD_strx_to_uint32_n_() failed %d time%s.\n\n",
- strx_to_uint32_n_fails, strx_to_uint32_n_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_strx_to_uint32_n_() failed %d time%s.\n\n",
+ strx_to_uint32_n_fails, strx_to_uint32_n_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_strx_to_uint32_n_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_strx_to_uint32_n_() successfully passed all checks.\n\n");
- res = check_strx_to_uint64_valid();
+ res = check_strx_to_uint64_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_valid().\n");
- return 99;
- }
- strx_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_valid().\n");
+ return 99;
}
+ strx_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_valid() successfully passed.\n\n");
- res = check_strx_to_uint64_all_chars();
+ res = check_strx_to_uint64_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_all_chars().\n");
- return 99;
- }
- strx_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_all_chars().\n");
+ return 99;
}
+ strx_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_all_chars() successfully passed.\n\n");
- res = check_strx_to_uint64_overflow();
+ res = check_strx_to_uint64_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_overflow().\n");
- return 99;
- }
- strx_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_overflow().\n");
+ return 99;
}
+ strx_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_overflow() successfully passed.\n\n");
- res = check_strx_to_uint64_no_val();
+ res = check_strx_to_uint64_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_no_val().\n");
- return 99;
- }
- strx_to_uint64_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_no_val().\n");
+ return 99;
}
+ strx_to_uint64_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_no_val() successfully passed.\n\n");
if (strx_to_uint64_fails)
- fprintf(stderr, "FAILED: function MHD_strx_to_uint64_() failed %d time%s.\n\n",
- strx_to_uint64_fails, strx_to_uint64_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_strx_to_uint64_() failed %d time%s.\n\n",
+ strx_to_uint64_fails, strx_to_uint64_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_strx_to_uint64_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_strx_to_uint64_() successfully passed all checks.\n\n");
- res = check_strx_to_uint64_n_valid();
+ res = check_strx_to_uint64_n_valid ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_n_valid().\n");
- return 99;
- }
- strx_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_n_valid() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_n_valid().\n");
+ return 99;
}
+ strx_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_n_valid() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_n_valid() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_n_valid() successfully passed.\n\n");
- res = check_strx_to_uint64_n_all_chars();
+ res = check_strx_to_uint64_n_all_chars ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_n_all_chars().\n");
- return 99;
- }
- strx_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_n_all_chars() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_n_all_chars().\n");
+ return 99;
}
+ strx_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_n_all_chars() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_n_all_chars() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_n_all_chars() successfully passed.\n\n");
- res = check_strx_to_uint64_n_overflow();
+ res = check_strx_to_uint64_n_overflow ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_n_overflow().\n");
- return 99;
- }
- strx_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_n_overflow() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_n_overflow().\n");
+ return 99;
}
+ strx_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_n_overflow() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_n_overflow() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_n_overflow() successfully passed.\n\n");
- res = check_strx_to_uint64_n_no_val();
+ res = check_strx_to_uint64_n_no_val ();
if (res != 0)
+ {
+ if (res < 0)
{
- if (res < 0)
- {
- fprintf(stderr, "ERROR: test internal error in check_strx_to_uint64_n_no_val().\n");
- return 99;
- }
- strx_to_uint64_n_fails += res;
- fprintf(stderr, "FAILED: testcase check_strx_to_uint64_n_no_val() failed.\n\n");
+ fprintf (stderr,
+ "ERROR: test internal error in check_strx_to_uint64_n_no_val().\n");
+ return 99;
}
+ strx_to_uint64_n_fails += res;
+ fprintf (stderr,
+ "FAILED: testcase check_strx_to_uint64_n_no_val() failed.\n\n");
+ }
else if (verbose > 1)
- printf("PASSED: testcase check_strx_to_uint64_n_no_val() successfully passed.\n\n");
+ printf (
+ "PASSED: testcase check_strx_to_uint64_n_no_val() successfully passed.\n\n");
if (strx_to_uint64_n_fails)
- fprintf(stderr, "FAILED: function MHD_strx_to_uint64_n_() failed %d time%s.\n\n",
- strx_to_uint64_n_fails, strx_to_uint64_n_fails == 1 ? "" : "s");
+ fprintf (stderr,
+ "FAILED: function MHD_strx_to_uint64_n_() failed %d time%s.\n\n",
+ strx_to_uint64_n_fails, strx_to_uint64_n_fails == 1 ? "" : "s");
else if (verbose > 0)
- printf("PASSED: function MHD_strx_to_uint64_n_() successfully passed all checks.\n\n");
+ printf (
+ "PASSED: function MHD_strx_to_uint64_n_() successfully passed all checks.\n\n");
if (str_to_uint64_fails || str_to_uint64_n_fails ||
strx_to_uint32_fails || strx_to_uint32_n_fails ||
strx_to_uint64_fails || strx_to_uint64_n_fails)
- {
- if (verbose > 0)
- printf("At least one test failed.\n");
+ {
+ if (verbose > 0)
+ printf ("At least one test failed.\n");
- return 1;
- }
+ return 1;
+ }
if (verbose > 0)
- printf("All tests passed successfully.\n");
+ printf ("All tests passed successfully.\n");
return 0;
}
-int main(int argc, char * argv[])
+int
+main (int argc, char *argv[])
{
- if (has_param(argc, argv, "-v") || has_param(argc, argv, "--verbose") || has_param(argc, argv, "--verbose1"))
+ if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose") ||
+ has_param (argc, argv, "--verbose1"))
verbose = 1;
- if (has_param(argc, argv, "-vv") || has_param(argc, argv, "--verbose2"))
+ if (has_param (argc, argv, "-vv") || has_param (argc, argv, "--verbose2"))
verbose = 2;
- if (has_param(argc, argv, "-vvv") || has_param(argc, argv, "--verbose3"))
+ if (has_param (argc, argv, "-vvv") || has_param (argc, argv, "--verbose3"))
verbose = 3;
- if (has_in_name(argv[0], "_to_value"))
- return run_str_to_X_tests();
+ if (has_in_name (argv[0], "_to_value"))
+ return run_str_to_X_tests ();
- return run_eq_neq_str_tests();
+ return run_eq_neq_str_tests ();
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_str_token.c
^
|
@@ -29,89 +29,100 @@
static int
-expect_found_n(const char *str, const char *token, size_t token_len)
+expect_found_n (const char *str, const char *token, size_t token_len)
{
- if (!MHD_str_has_token_caseless_(str, token, token_len))
- {
- fprintf(stderr, "MHD_str_has_token_caseless_() FAILED:\n\tMHD_str_has_token_caseless_(%s, %s, %lu) return false\n",
- str, token, (unsigned long) token_len);
- return 1;
- }
+ if (! MHD_str_has_token_caseless_ (str, token, token_len))
+ {
+ fprintf (stderr,
+ "MHD_str_has_token_caseless_() FAILED:\n\tMHD_str_has_token_caseless_(%s, %s, %lu) return false\n",
+ str, token, (unsigned long) token_len);
+ return 1;
+ }
return 0;
}
-#define expect_found(s,t) expect_found_n((s),(t),MHD_STATICSTR_LEN_(t))
+
+#define expect_found(s,t) expect_found_n ((s),(t),MHD_STATICSTR_LEN_ (t))
static int
-expect_not_found_n(const char *str, const char *token, size_t token_len)
+expect_not_found_n (const char *str, const char *token, size_t token_len)
{
- if (MHD_str_has_token_caseless_(str, token, token_len))
- {
- fprintf(stderr, "MHD_str_has_token_caseless_() FAILED:\n\tMHD_str_has_token_caseless_(%s, %s, %lu) return true\n",
- str, token, (unsigned long) token_len);
- return 1;
- }
+ if (MHD_str_has_token_caseless_ (str, token, token_len))
+ {
+ fprintf (stderr,
+ "MHD_str_has_token_caseless_() FAILED:\n\tMHD_str_has_token_caseless_(%s, %s, %lu) return true\n",
+ str, token, (unsigned long) token_len);
+ return 1;
+ }
return 0;
}
-#define expect_not_found(s,t) expect_not_found_n((s),(t),MHD_STATICSTR_LEN_(t))
-int check_match(void)
+#define expect_not_found(s,t) expect_not_found_n ((s),(t),MHD_STATICSTR_LEN_ ( \
+ t))
+
+int
+check_match (void)
{
int errcount = 0;
- errcount += expect_found("string", "string");
- errcount += expect_found("String", "string");
- errcount += expect_found("string", "String");
- errcount += expect_found("strinG", "String");
- errcount += expect_found("\t strinG", "String");
- errcount += expect_found("strinG\t ", "String");
- errcount += expect_found(" \t tOkEn ", "toKEN");
- errcount += expect_found("not token\t, tOkEn ", "toKEN");
- errcount += expect_found("not token,\t tOkEn, more token", "toKEN");
- errcount += expect_found("not token,\t tOkEn\t, more token", "toKEN");
- errcount += expect_found(",,,,,,test,,,,", "TESt");
- errcount += expect_found(",,,,,\t,test,,,,", "TESt");
- errcount += expect_found(",,,,,,test, ,,,", "TESt");
- errcount += expect_found(",,,,,, test,,,,", "TESt");
- errcount += expect_found(",,,,,, test not,test,,", "TESt");
- errcount += expect_found(",,,,,, test not,,test,,", "TESt");
- errcount += expect_found(",,,,,, test not ,test,,", "TESt");
- errcount += expect_found(",,,,,, test", "TESt");
- errcount += expect_found(",,,,,, test ", "TESt");
- errcount += expect_found("no test,,,,,, test ", "TESt");
+ errcount += expect_found ("string", "string");
+ errcount += expect_found ("String", "string");
+ errcount += expect_found ("string", "String");
+ errcount += expect_found ("strinG", "String");
+ errcount += expect_found ("\t strinG", "String");
+ errcount += expect_found ("strinG\t ", "String");
+ errcount += expect_found (" \t tOkEn ", "toKEN");
+ errcount += expect_found ("not token\t, tOkEn ", "toKEN");
+ errcount += expect_found ("not token,\t tOkEn, more token", "toKEN");
+ errcount += expect_found ("not token,\t tOkEn\t, more token", "toKEN");
+ errcount += expect_found (",,,,,,test,,,,", "TESt");
+ errcount += expect_found (",,,,,\t,test,,,,", "TESt");
+ errcount += expect_found (",,,,,,test, ,,,", "TESt");
+ errcount += expect_found (",,,,,, test,,,,", "TESt");
+ errcount += expect_found (",,,,,, test not,test,,", "TESt");
+ errcount += expect_found (",,,,,, test not,,test,,", "TESt");
+ errcount += expect_found (",,,,,, test not ,test,,", "TESt");
+ errcount += expect_found (",,,,,, test", "TESt");
+ errcount += expect_found (",,,,,, test ", "TESt");
+ errcount += expect_found ("no test,,,,,, test ", "TESt");
return errcount;
}
-int check_not_match(void)
+
+int
+check_not_match (void)
{
int errcount = 0;
- errcount += expect_not_found("strin", "string");
- errcount += expect_not_found("Stringer", "string");
- errcount += expect_not_found("sstring", "String");
- errcount += expect_not_found("string", "Strin");
- errcount += expect_not_found("\t( strinG", "String");
- errcount += expect_not_found(")strinG\t ", "String");
- errcount += expect_not_found(" \t tOkEn t ", "toKEN");
- errcount += expect_not_found("not token\t, tOkEner ", "toKEN");
- errcount += expect_not_found("not token,\t tOkEns, more token", "toKEN");
- errcount += expect_not_found("not token,\t tOkEns\t, more token", "toKEN");
- errcount += expect_not_found(",,,,,,testing,,,,", "TESt");
- errcount += expect_not_found(",,,,,\t,test,,,,", "TESting");
- errcount += expect_not_found("tests,,,,,,quest, ,,,", "TESt");
- errcount += expect_not_found(",,,,,, testы,,,,", "TESt");
- errcount += expect_not_found(",,,,,, test not,хtest,,", "TESt");
- errcount += expect_not_found("testing,,,,,, test not,,test2,,", "TESt");
- errcount += expect_not_found(",testi,,,,, test not ,test,,", "TESting");
- errcount += expect_not_found(",,,,,,2 test", "TESt");
- errcount += expect_not_found(",,,,,,test test ", "test");
- errcount += expect_not_found("no test,,,,,, test test", "test");
+ errcount += expect_not_found ("strin", "string");
+ errcount += expect_not_found ("Stringer", "string");
+ errcount += expect_not_found ("sstring", "String");
+ errcount += expect_not_found ("string", "Strin");
+ errcount += expect_not_found ("\t( strinG", "String");
+ errcount += expect_not_found (")strinG\t ", "String");
+ errcount += expect_not_found (" \t tOkEn t ", "toKEN");
+ errcount += expect_not_found ("not token\t, tOkEner ", "toKEN");
+ errcount += expect_not_found ("not token,\t tOkEns, more token", "toKEN");
+ errcount += expect_not_found ("not token,\t tOkEns\t, more token", "toKEN");
+ errcount += expect_not_found (",,,,,,testing,,,,", "TESt");
+ errcount += expect_not_found (",,,,,\t,test,,,,", "TESting");
+ errcount += expect_not_found ("tests,,,,,,quest, ,,,", "TESt");
+ errcount += expect_not_found (",,,,,, testы,,,,", "TESt");
+ errcount += expect_not_found (",,,,,, test not,хtest,,", "TESt");
+ errcount += expect_not_found ("testing,,,,,, test not,,test2,,", "TESt");
+ errcount += expect_not_found (",testi,,,,, test not ,test,,", "TESting");
+ errcount += expect_not_found (",,,,,,2 test", "TESt");
+ errcount += expect_not_found (",,,,,,test test ", "test");
+ errcount += expect_not_found ("no test,,,,,, test test", "test");
return errcount;
}
-int main(int argc, char * argv[])
+
+int
+main (int argc, char *argv[])
{
int errcount = 0;
- errcount += check_match();
- errcount += check_not_match();
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+ errcount += check_match ();
+ errcount += check_not_match ();
return errcount == 0 ? 0 : 1;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_upgrade.c
^
|
@@ -82,7 +82,7 @@
*/
static pid_t
gnutlscli_connect (int *sock,
- uint16_t port)
+ uint16_t port)
{
pid_t chld;
int sp[2];
@@ -95,55 +95,59 @@
return -1;
chld = fork ();
if (0 != chld)
- {
- *sock = sp[1];
- MHD_socket_close_chk_ (sp[0]);
- return chld;
- }
+ {
+ *sock = sp[1];
+ MHD_socket_close_chk_ (sp[0]);
+ return chld;
+ }
MHD_socket_close_chk_ (sp[1]);
(void) close (0);
(void) close (1);
- dup2 (sp[0], 0);
- dup2 (sp[0], 1);
+ if (-1 == dup2 (sp[0], 0))
+ abort ();
+ if (-1 == dup2 (sp[0], 1))
+ abort ();
MHD_socket_close_chk_ (sp[0]);
if (TLS_CLI_GNUTLS == use_tls_tool)
- {
- snprintf (destination,
- sizeof(destination),
- "%u",
- (unsigned int) port);
- execlp ("gnutls-cli",
- "gnutls-cli",
- "--insecure",
- "-p",
- destination,
- "127.0.0.1",
- (char *) NULL);
- }
+ {
+ snprintf (destination,
+ sizeof(destination),
+ "%u",
+ (unsigned int) port);
+ execlp ("gnutls-cli",
+ "gnutls-cli",
+ "--insecure",
+ "-p",
+ destination,
+ "127.0.0.1",
+ (char *) NULL);
+ }
else if (TLS_CLI_OPENSSL == use_tls_tool)
- {
- snprintf (destination,
- sizeof(destination),
- "127.0.0.1:%u",
- (unsigned int) port);
- execlp ("openssl",
- "openssl",
- "s_client",
- "-connect",
- destination,
- "-verify",
- "1",
- (char *) NULL);
- }
+ {
+ snprintf (destination,
+ sizeof(destination),
+ "127.0.0.1:%u",
+ (unsigned int) port);
+ execlp ("openssl",
+ "openssl",
+ "s_client",
+ "-connect",
+ destination,
+ "-verify",
+ "1",
+ (char *) NULL);
+ }
_exit (1);
}
+
+
#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
/**
* Wrapper structure for plain&TLS sockets
*/
-struct wr_socket_strc
+struct wr_socket
{
/**
* Real network socket
@@ -179,18 +183,6 @@
/**
- * Pseudo type for plain&TLS sockets
- */
-typedef struct wr_socket_strc* wr_socket;
-
-
-/**
- * Invalid value of wr_socket
- */
-#define WR_BAD (NULL)
-
-
-/**
* Get underlying real socket.
* @return FD of real socket
*/
@@ -199,62 +191,68 @@
/**
* Create wr_socket with plain TCP underlying socket
- * @return created socket on success, WR_BAD otherwise
+ * @return created socket on success, NULL otherwise
*/
-static wr_socket wr_create_plain_sckt(void)
+static struct wr_socket *
+wr_create_plain_sckt (void)
{
- wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc));
- if (WR_BAD == s)
- return WR_BAD;
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+ if (NULL == s)
+ return NULL;
s->t = wr_plain;
s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MHD_INVALID_SOCKET != s->fd)
return s;
- free(s);
- return WR_BAD;
+ free (s);
+ return NULL;
}
/**
* Create wr_socket with TLS TCP underlying socket
- * @return created socket on success, WR_BAD otherwise
+ * @return created socket on success, NULL otherwise
*/
-static wr_socket wr_create_tls_sckt(void)
+static struct wr_socket *
+wr_create_tls_sckt (void)
{
#ifdef HTTPS_SUPPORT
- wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc));
- if (WR_BAD == s)
- return WR_BAD;
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+ if (NULL == s)
+ return NULL;
s->t = wr_tls;
s->tls_connected = 0;
s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MHD_INVALID_SOCKET != s->fd)
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_init (&(s->tls_s), GNUTLS_CLIENT))
{
- if (GNUTLS_E_SUCCESS == gnutls_init (&(s->tls_s), GNUTLS_CLIENT))
+ if (GNUTLS_E_SUCCESS == gnutls_set_default_priority (s->tls_s))
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_certificate_allocate_credentials (
+ &(s->tls_crd)))
{
- if (GNUTLS_E_SUCCESS == gnutls_set_default_priority (s->tls_s))
- {
- if (GNUTLS_E_SUCCESS == gnutls_certificate_allocate_credentials (&(s->tls_crd)))
- {
- if (GNUTLS_E_SUCCESS == gnutls_credentials_set (s->tls_s, GNUTLS_CRD_CERTIFICATE, s->tls_crd))
- {
-#if GNUTLS_VERSION_NUMBER+0 >= 0x030109
- gnutls_transport_set_int (s->tls_s, (int)(s->fd));
+ if (GNUTLS_E_SUCCESS == gnutls_credentials_set (s->tls_s,
+ GNUTLS_CRD_CERTIFICATE,
+ s->tls_crd))
+ {
+#if GNUTLS_VERSION_NUMBER + 0 >= 0x030109
+ gnutls_transport_set_int (s->tls_s, (int) (s->fd));
#else /* GnuTLS before 3.1.9 */
- gnutls_transport_set_ptr (s->tls_s, (gnutls_transport_ptr_t)(intptr_t)(s->fd));
+ gnutls_transport_set_ptr (s->tls_s,
+ (gnutls_transport_ptr_t) (intptr_t) (s->fd));
#endif /* GnuTLS before 3.1.9 */
- return s;
- }
- gnutls_certificate_free_credentials (s->tls_crd);
- }
- }
- gnutls_deinit (s->tls_s);
+ return s;
+ }
+ gnutls_certificate_free_credentials (s->tls_crd);
}
- (void)MHD_socket_close_ (s->fd);
+ }
+ gnutls_deinit (s->tls_s);
}
- free(s);
+ (void) MHD_socket_close_ (s->fd);
+ }
+ free (s);
#endif /* HTTPS_SUPPORT */
- return WR_BAD;
+ return NULL;
}
@@ -262,13 +260,15 @@
* Create wr_socket with plain TCP underlying socket
* from already created TCP socket.
* @param plain_sk real TCP socket
- * @return created socket on success, WR_BAD otherwise
+ * @return created socket on success, NULL otherwise
*/
-static wr_socket wr_create_from_plain_sckt(MHD_socket plain_sk)
+static struct wr_socket *
+wr_create_from_plain_sckt (MHD_socket plain_sk)
{
- wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc));
- if (WR_BAD == s)
- return WR_BAD;
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+
+ if (NULL == s)
+ return NULL;
s->t = wr_plain;
s->fd = plain_sk;
return s;
@@ -279,53 +279,50 @@
* Connect socket to specified address.
* @param s socket to use
* @param addr address to connect
- * @param length of sturcture pointed by @a addr
+ * @param length of structure pointed by @a addr
* @return zero on success, -1 otherwise.
*/
-static int wr_connect(wr_socket s, struct sockaddr * addr, int length)
+static int
+wr_connect (struct wr_socket *s,
+ const struct sockaddr *addr,
+ int length)
{
- if (0 != connect(s->fd, addr, length))
+ if (0 != connect (s->fd, addr, length))
return -1;
if (wr_plain == s->t)
return 0;
#ifdef HTTPS_SUPPORT
if (wr_tls == s->t)
- {
- s->tls_connected = 0;
- return 0;
- /* Do not try handshake here as
- * it require processing on MHD side and
- * when testing with "external" polling,
- * test will call MHD processing only
- * after return from wr_connect(). */
- /*
- int res = gnutls_handshake (s->tls_s);
- if (GNUTLS_E_SUCCESS == res)
- {
- s->tls_connected = !0;
- return 0;
- }
- if (GNUTLS_E_AGAIN == res)
- return 0;
- */
- }
+ {
+ /* Do not try handshake here as
+ * it require processing on MHD side and
+ * when testing with "external" polling,
+ * test will call MHD processing only
+ * after return from wr_connect(). */
+ s->tls_connected = 0;
+ return 0;
+ }
#endif /* HTTPS_SUPPORT */
return -1;
}
+
#ifdef HTTPS_SUPPORT
/* Only to be called from wr_send() and wr_recv() ! */
-static bool wr_handshake(wr_socket s)
+static bool
+wr_handshake (struct wr_socket *s)
{
int res = gnutls_handshake (s->tls_s);
if (GNUTLS_E_SUCCESS == res)
- s->tls_connected = !0;
+ s->tls_connected = true;
else if (GNUTLS_E_AGAIN == res)
MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
else
MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
return s->tls_connected;
}
+
+
#endif /* HTTPS_SUPPORT */
@@ -338,25 +335,28 @@
* -1 if failed. Use #MHD_socket_get_error_()
* to get socket error.
*/
-static ssize_t wr_send(wr_socket s, const void *buf, size_t len)
+static ssize_t
+wr_send (struct wr_socket *s,
+ const void *buf,
+ size_t len)
{
if (wr_plain == s->t)
- return MHD_send_(s->fd, buf, len);
+ return MHD_send_ (s->fd, buf, len);
#ifdef HTTPS_SUPPORT
if (wr_tls == s->t)
- {
- ssize_t ret;
- if (!s->tls_connected && !wr_handshake (s))
- return -1;
-
- ret = gnutls_record_send (s->tls_s, buf, len);
- if (ret > 0)
- return ret;
- if (GNUTLS_E_AGAIN == ret)
- MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
- else
- MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
- }
+ {
+ ssize_t ret;
+ if (! s->tls_connected && ! wr_handshake (s))
+ return -1;
+
+ ret = gnutls_record_send (s->tls_s, buf, len);
+ if (ret > 0)
+ return ret;
+ if (GNUTLS_E_AGAIN == ret)
+ MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
+ else
+ MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
+ }
#endif /* HTTPS_SUPPORT */
return -1;
}
@@ -371,25 +371,28 @@
* -1 if failed. Use #MHD_socket_get_error_()
* to get socket error.
*/
-static ssize_t wr_recv(wr_socket s, void *buf, size_t len)
+static ssize_t
+wr_recv (struct wr_socket *s,
+ void *buf,
+ size_t len)
{
if (wr_plain == s->t)
return MHD_recv_ (s->fd, buf, len);
#ifdef HTTPS_SUPPORT
if (wr_tls == s->t)
- {
- ssize_t ret;
- if (!s->tls_connected && !wr_handshake (s))
- return -1;
-
- ret = gnutls_record_recv (s->tls_s, buf, len);
- if (ret > 0)
- return ret;
- if (GNUTLS_E_AGAIN == ret)
- MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
- else
- MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
- }
+ {
+ ssize_t ret;
+ if (! s->tls_connected && ! wr_handshake (s))
+ return -1;
+
+ ret = gnutls_record_recv (s->tls_s, buf, len);
+ if (ret > 0)
+ return ret;
+ if (GNUTLS_E_AGAIN == ret)
+ MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
+ else
+ MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
+ }
#endif /* HTTPS_SUPPORT */
return -1;
}
@@ -401,17 +404,17 @@
* @return zero on succeed, -1 otherwise
*/
static int
-wr_close(wr_socket s)
+wr_close (struct wr_socket *s)
{
- int ret = (MHD_socket_close_(s->fd)) ? 0 : -1;
+ int ret = (MHD_socket_close_ (s->fd)) ? 0 : -1;
#ifdef HTTPS_SUPPORT
if (wr_tls == s->t)
- {
- gnutls_deinit (s->tls_s);
- gnutls_certificate_free_credentials (s->tls_crd);
- }
+ {
+ gnutls_deinit (s->tls_s);
+ gnutls_certificate_free_credentials (s->tls_crd);
+ }
#endif /* HTTPS_SUPPORT */
- free(s);
+ free (s);
return ret;
}
@@ -424,7 +427,7 @@
/**
* Will be set to the upgraded socket.
*/
-static wr_socket usock;
+static struct wr_socket *usock;
/**
* Thread we use to run the interaction with the upgraded socket.
@@ -437,19 +440,35 @@
static volatile bool done;
+/**
+ * Callback used by MHD to notify the application about completed
+ * requests. Frees memory.
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param con_cls value as set by the last call to
+ * the #MHD_AccessHandlerCallback
+ * @param toe reason for request termination
+ */
static void
notify_completed_cb (void *cls,
struct MHD_Connection *connection,
void **con_cls,
enum MHD_RequestTerminationCode toe)
{
+ pthread_t*ppth = *con_cls;
+
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
if ( (toe != MHD_REQUEST_TERMINATED_COMPLETED_OK) &&
(toe != MHD_REQUEST_TERMINATED_CLIENT_ABORT) &&
(toe != MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN) )
abort ();
- if (! pthread_equal (**((pthread_t**)con_cls), pthread_self ()))
+ if (! pthread_equal (**((pthread_t**) con_cls),
+ pthread_self ()))
abort ();
- free (*con_cls);
+ if (NULL != ppth)
+ free (*con_cls);
*con_cls = NULL;
}
@@ -467,13 +486,16 @@
const char *uri,
struct MHD_Connection *connection)
{
- pthread_t* ppth;
+ pthread_t *ppth;
+
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
if (0 != strcmp (uri,
"/"))
abort ();
- ppth = (pthread_t*) malloc (sizeof(pthread_t));
+ ppth = malloc (sizeof (pthread_t));
if (NULL == ppth)
- abort();
+ abort ();
*ppth = pthread_self ();
return (void *) ppth;
}
@@ -506,6 +528,8 @@
{
static int started;
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
switch (toe)
{
case MHD_CONNECTION_NOTIFY_STARTED:
@@ -554,28 +578,29 @@
static void
-send_all (wr_socket sock,
+send_all (struct wr_socket *sock,
const char *text)
{
size_t len = strlen (text);
ssize_t ret;
+ size_t off;
make_blocking (wr_fd (sock));
- for (size_t off = 0; off < len; off += ret)
+ for (off = 0; off < len; off += ret)
+ {
+ ret = wr_send (sock,
+ &text[off],
+ len - off);
+ if (0 > ret)
{
- ret = wr_send (sock,
- &text[off],
- len - off);
- if (0 > ret)
- {
- if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
- {
- ret = 0;
- continue;
- }
- abort ();
- }
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
+ {
+ ret = 0;
+ continue;
+ }
+ abort ();
}
+ }
}
@@ -584,7 +609,7 @@
* get '\r\n\r\n'.
*/
static void
-recv_hdr (wr_socket sock)
+recv_hdr (struct wr_socket *sock)
{
unsigned int i;
char next;
@@ -595,65 +620,66 @@
next = '\r';
i = 0;
while (i < 4)
+ {
+ ret = wr_recv (sock,
+ &c,
+ 1);
+ if (0 > ret)
{
- ret = wr_recv (sock,
- &c,
- 1);
- if (0 > ret)
- {
- if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
- continue;
- abort ();
- }
- if (0 == ret)
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
continue;
- if (c == next)
- {
- i++;
- if (next == '\r')
- next = '\n';
- else
- next = '\r';
- continue;
- }
- if (c == '\r')
- {
- i = 1;
- next = '\n';
- continue;
- }
- i = 0;
- next = '\r';
+ abort ();
+ }
+ if (0 == ret)
+ continue;
+ if (c == next)
+ {
+ i++;
+ if (next == '\r')
+ next = '\n';
+ else
+ next = '\r';
+ continue;
}
+ if (c == '\r')
+ {
+ i = 1;
+ next = '\n';
+ continue;
+ }
+ i = 0;
+ next = '\r';
+ }
}
static void
-recv_all (wr_socket sock,
+recv_all (struct wr_socket *sock,
const char *text)
{
size_t len = strlen (text);
char buf[len];
ssize_t ret;
+ size_t off;
make_blocking (wr_fd (sock));
- for (size_t off = 0; off < len; off += ret)
+ for (off = 0; off < len; off += ret)
+ {
+ ret = wr_recv (sock,
+ &buf[off],
+ len - off);
+ if (0 > ret)
{
- ret = wr_recv (sock,
- &buf[off],
- len - off);
- if (0 > ret)
- {
- if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
- {
- ret = 0;
- continue;
- }
- abort ();
- }
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
+ {
+ ret = 0;
+ continue;
+ }
+ abort ();
}
+ }
if (0 != strncmp (text, buf, len))
- abort();
+ abort ();
}
@@ -676,6 +702,8 @@
"Finished");
MHD_upgrade_action (urh,
MHD_UPGRADE_ACTION_CLOSE);
+ free (usock);
+ usock = NULL;
return NULL;
}
@@ -689,18 +717,18 @@
static void *
run_usock_client (void *cls)
{
- wr_socket *sock = cls;
+ struct wr_socket *sock = cls;
- send_all (*sock,
+ send_all (sock,
"GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n");
- recv_hdr (*sock);
- recv_all (*sock,
+ recv_hdr (sock);
+ recv_all (sock,
"Hello");
- send_all (*sock,
+ send_all (sock,
"World");
- recv_all (*sock,
+ recv_all (sock,
"Finished");
- wr_close (*sock);
+ wr_close (sock);
done = true;
return NULL;
}
@@ -759,6 +787,11 @@
MHD_socket sock,
struct MHD_UpgradeResponseHandle *urh)
{
+ (void) cls;
+ (void) connection;
+ (void) con_cls;
+ (void) extra_in; /* Unused. Silent compiler warning. */
+
usock = wr_create_from_plain_sckt (sock);
if (0 != extra_in_size)
abort ();
@@ -806,10 +839,10 @@
* can be set with the #MHD_OPTION_NOTIFY_COMPLETED).
* Initially, `*con_cls` will be NULL.
* @return #MHD_YES if the connection was handled successfully,
- * #MHD_NO if the socket must be closed due to a serios
+ * #MHD_NO if the socket must be closed due to a serious
* error while handling the request
*/
-static int
+static enum MHD_Result
ahc_upgrade (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -820,11 +853,17 @@
void **con_cls)
{
struct MHD_Response *resp;
- int ret;
+ enum MHD_Result ret;
+ (void) cls;
+ (void) url;
+ (void) method; /* Unused. Silent compiler warning. */
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (NULL == *con_cls)
abort ();
- if (! pthread_equal (**((pthread_t**)con_cls), pthread_self ()))
+ if (! pthread_equal (**((pthread_t**) con_cls), pthread_self ()))
abort ();
resp = MHD_create_response_for_upgrade (&upgrade_cb,
NULL);
@@ -855,39 +894,40 @@
struct timeval tv;
while (! done)
- {
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- max_fd = -1;
+ {
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ max_fd = -1;
+ to = 1000;
+
+ if (MHD_YES !=
+ MHD_get_fdset (daemon,
+ &rs,
+ &ws,
+ &es,
+ &max_fd))
+ abort ();
+ (void) MHD_get_timeout (daemon,
+ &to);
+ if (1000 < to)
to = 1000;
-
- if (MHD_YES !=
- MHD_get_fdset (daemon,
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = 1000 * (to % 1000);
+ if (0 > MHD_SYS_select_ (max_fd + 1,
+ &rs,
+ &ws,
+ &es,
+ &tv))
+ abort ();
+ MHD_run_from_select (daemon,
&rs,
&ws,
- &es,
- &max_fd))
- abort ();
- (void) MHD_get_timeout (daemon,
- &to);
- if (1000 < to)
- to = 1000;
- tv.tv_sec = to / 1000;
- tv.tv_usec = 1000 * (to % 1000);
- if (0 > MHD_SYS_select_ (max_fd + 1,
- &rs,
- &ws,
- &es,
- &tv))
- abort ();
- MHD_run_from_select (daemon,
- &rs,
- &ws,
- &es);
- }
+ &es);
+ }
}
+
#ifdef HAVE_POLL
/**
@@ -898,8 +938,11 @@
static void
run_mhd_poll_loop (struct MHD_Daemon *daemon)
{
+ (void) daemon; /* Unused. Silent compiler warning. */
abort (); /* currently not implementable with existing MHD API */
}
+
+
#endif /* HAVE_POLL */
@@ -917,30 +960,37 @@
fd_set rs;
MHD_UNSIGNED_LONG_LONG to;
struct timeval tv;
+ int ret;
di = MHD_get_daemon_info (daemon,
MHD_DAEMON_INFO_EPOLL_FD);
ep = di->listen_fd;
while (! done)
- {
- FD_ZERO (&rs);
- to = 1000;
+ {
+ FD_ZERO (&rs);
+ to = 1000;
- FD_SET (ep, &rs);
- (void) MHD_get_timeout (daemon,
- &to);
- if (1000 < to)
- to = 1000;
- tv.tv_sec = to / 1000;
- tv.tv_usec = 1000 * (to % 1000);
- select (ep + 1,
- &rs,
- NULL,
- NULL,
- &tv);
- MHD_run (daemon);
- }
+ FD_SET (ep, &rs);
+ (void) MHD_get_timeout (daemon,
+ &to);
+ if (1000 < to)
+ to = 1000;
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = 1000 * (to % 1000);
+ ret = select (ep + 1,
+ &rs,
+ NULL,
+ NULL,
+ &tv);
+ if ( (-1 == ret) &&
+ (EAGAIN != errno) &&
+ (EINTR != errno) )
+ abort ();
+ MHD_run (daemon);
+ }
}
+
+
#endif /* EPOLL_SUPPORT */
/**
@@ -966,6 +1016,7 @@
abort ();
}
+
static bool test_tls;
/**
@@ -979,34 +1030,44 @@
unsigned int pool)
{
struct MHD_Daemon *d = NULL;
- wr_socket sock;
+ struct wr_socket *sock;
struct sockaddr_in sa;
const union MHD_DaemonInfo *real_flags;
+ const union MHD_DaemonInfo *dinfo;
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
pid_t pid = -1;
#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
done = false;
- if (!test_tls)
+ if (! test_tls)
d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE,
- 1080,
- NULL, NULL,
- &ahc_upgrade, NULL,
- MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb, NULL,
- MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb, NULL,
- MHD_OPTION_THREAD_POOL_SIZE, pool,
- MHD_OPTION_END);
+ MHD_is_feature_supported (
+ MHD_FEATURE_AUTODETECT_BIND_PORT) ?
+ 0 : 1090,
+ NULL, NULL,
+ &ahc_upgrade, NULL,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb,
+ NULL,
+ MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb,
+ NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, pool,
+ MHD_OPTION_END);
#ifdef HTTPS_SUPPORT
else
- d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE | MHD_USE_TLS,
- 1080,
+ d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE
+ | MHD_USE_TLS,
+ MHD_is_feature_supported (
+ MHD_FEATURE_AUTODETECT_BIND_PORT) ?
+ 0 : 1090,
NULL, NULL,
&ahc_upgrade, NULL,
MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb, NULL,
- MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb,
+ NULL,
+ MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb,
+ NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
MHD_OPTION_THREAD_POOL_SIZE, pool,
@@ -1014,52 +1075,74 @@
#endif /* HTTPS_SUPPORT */
if (NULL == d)
return 2;
- real_flags = MHD_get_daemon_info(d, MHD_DAEMON_INFO_FLAGS);
+ real_flags = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_FLAGS);
if (NULL == real_flags)
abort ();
- if (!test_tls || TLS_LIB_GNUTLS == use_tls_tool)
- {
- sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt ();
- if (WR_BAD == sock)
- abort ();
- sa.sin_family = AF_INET;
- sa.sin_port = htons (1080);
- sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- if (0 != wr_connect (sock,
- (struct sockaddr *) &sa,
- sizeof (sa)))
- abort ();
- }
+ dinfo = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_BIND_PORT);
+ if ( (NULL == dinfo) ||
+ (0 == dinfo->port) )
+ abort ();
+ if (! test_tls || (TLS_LIB_GNUTLS == use_tls_tool))
+ {
+ sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt ();
+ if (NULL == sock)
+ abort ();
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons (dinfo->port);
+ sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (0 != wr_connect (sock,
+ (struct sockaddr *) &sa,
+ sizeof (sa)))
+ abort ();
+ }
else
- {
+ {
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
- MHD_socket tls_fork_sock;
- if (-1 == (pid = gnutlscli_connect (&tls_fork_sock, 1080)))
- {
- MHD_stop_daemon (d);
- return 4;
- }
- sock = wr_create_from_plain_sckt (tls_fork_sock);
- if (WR_BAD == sock)
- abort ();
-#else /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
+ MHD_socket tls_fork_sock;
+ uint16_t port;
+
+ /* make address sanitizer happy */
+ memcpy (&port,
+ dinfo /* ->port */,
+ sizeof (port));
+ if (-1 == (pid = gnutlscli_connect (&tls_fork_sock,
+ port)))
+ {
+ MHD_stop_daemon (d);
+ return 4;
+ }
+
+ sock = wr_create_from_plain_sckt (tls_fork_sock);
+ if (NULL == sock)
abort ();
+#else /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
+ abort ();
#endif /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
- }
+ }
if (0 != pthread_create (&pt_client,
NULL,
&run_usock_client,
- &sock))
+ sock))
abort ();
if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
- run_mhd_loop (d, real_flags->flags);
+ {
+ enum MHD_FLAG used_flags;
+
+ /* make address sanitizer happy */
+ memcpy (&used_flags,
+ real_flags /* ->flags */,
+ sizeof (used_flags));
+ run_mhd_loop (d, used_flags);
+ }
pthread_join (pt_client,
NULL);
pthread_join (pt,
NULL);
#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
- if (test_tls && TLS_LIB_GNUTLS != use_tls_tool)
+ if (test_tls && (TLS_LIB_GNUTLS != use_tls_tool))
waitpid (pid, NULL, 0);
#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
MHD_stop_daemon (d);
@@ -1075,64 +1158,69 @@
int res;
use_tls_tool = TLS_CLI_NO_TOOL;
- test_tls = has_in_name(argv[0], "_tls");
+ test_tls = has_in_name (argv[0], "_tls");
- if (has_param(argc, argv, "-v") || has_param(argc, argv, "--verbose"))
- verbose = 1;
+ verbose = 1;
+ if (has_param (argc, argv, "-q") ||
+ has_param (argc, argv, "--quiet"))
+ verbose = 0;
if (test_tls)
- {
+ {
#ifdef HTTPS_SUPPORT
- if (has_param(argc, argv, "--use-gnutls-cli"))
- use_tls_tool = TLS_CLI_GNUTLS;
- else if (has_param(argc, argv, "--use-openssl"))
- use_tls_tool = TLS_CLI_OPENSSL;
- else if (has_param(argc, argv, "--use-gnutls-lib"))
- use_tls_tool = TLS_LIB_GNUTLS;
+ if (has_param (argc, argv, "--use-gnutls-cli"))
+ use_tls_tool = TLS_CLI_GNUTLS;
+ else if (has_param (argc, argv, "--use-openssl"))
+ use_tls_tool = TLS_CLI_OPENSSL;
+ else if (has_param (argc, argv, "--use-gnutls-lib"))
+ use_tls_tool = TLS_LIB_GNUTLS;
#if defined(HAVE_FORK) && defined(HAVE_WAITPID)
- else if (0 == system ("gnutls-cli --version 1> /dev/null"))
- use_tls_tool = TLS_CLI_GNUTLS;
- else if (0 == system ("openssl version 1> /dev/null"))
- use_tls_tool = TLS_CLI_OPENSSL;
+ else if (0 == system ("gnutls-cli --version 1> /dev/null 2> /dev/null"))
+ use_tls_tool = TLS_CLI_GNUTLS;
+ else if (0 == system ("openssl version 1> /dev/null 2> /dev/null"))
+ use_tls_tool = TLS_CLI_OPENSSL;
#endif /* HAVE_FORK && HAVE_WAITPID */
- else
- use_tls_tool = TLS_LIB_GNUTLS; /* Should be available as MHD use it. */
- if (verbose)
- {
- switch (use_tls_tool)
- {
- case TLS_CLI_GNUTLS:
- printf ("GnuTLS-CLI will be used for testing.\n");
- break;
- case TLS_CLI_OPENSSL:
- printf ("Command line version of OpenSSL will be used for testing.\n");
- break;
- case TLS_LIB_GNUTLS:
- printf ("GnuTLS library will be used for testing.\n");
- break;
- default:
- abort ();
- }
- }
- if ( (TLS_LIB_GNUTLS == use_tls_tool) &&
- (GNUTLS_E_SUCCESS != gnutls_global_init()) )
+ else
+ use_tls_tool = TLS_LIB_GNUTLS; /* Should be available as MHD use it. */
+ if (verbose)
+ {
+ switch (use_tls_tool)
+ {
+ case TLS_CLI_GNUTLS:
+ printf ("GnuTLS-CLI will be used for testing.\n");
+ break;
+ case TLS_CLI_OPENSSL:
+ printf ("Command line version of OpenSSL will be used for testing.\n");
+ break;
+ case TLS_LIB_GNUTLS:
+ printf ("GnuTLS library will be used for testing.\n");
+ break;
+ default:
abort ();
+ }
+ }
+ if ( (TLS_LIB_GNUTLS == use_tls_tool) &&
+ (GNUTLS_E_SUCCESS != gnutls_global_init ()) )
+ abort ();
#else /* ! HTTPS_SUPPORT */
- fprintf (stderr, "HTTPS support was disabled by configure.\n");
- return 77;
+ fprintf (stderr, "HTTPS support was disabled by configure.\n");
+ return 77;
#endif /* ! HTTPS_SUPPORT */
- }
+ }
/* run tests */
if (verbose)
- printf ("Starting HTTP \"Upgrade\" tests with %s connections.\n", test_tls ? "TLS" : "plain");
+ printf ("Starting HTTP \"Upgrade\" tests with %s connections.\n",
+ test_tls ? "TLS" : "plain");
/* try external select */
res = test_upgrade (0,
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with external select, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with external select, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with external select.\n");
@@ -1141,7 +1229,9 @@
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with external 'auto', return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with external 'auto', return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with external 'auto'.\n");
@@ -1150,33 +1240,44 @@
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with external select with EPOLL, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with external select with EPOLL, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with external select with EPOLL.\n");
#endif
/* Test thread-per-connection */
- res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION,
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION,
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with thread per connection, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with thread per connection.\n");
- res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION,
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION,
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with thread per connection and 'auto', return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection and 'auto', return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with thread per connection and 'auto'.\n");
#ifdef HAVE_POLL
- res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_POLL,
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_POLL,
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with thread per connection and poll, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection and poll, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with thread per connection and poll.\n");
#endif /* HAVE_POLL */
@@ -1186,28 +1287,36 @@
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal select, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal select, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal select.\n");
res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD,
2);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal select with thread pool, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal select with thread pool, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal select with thread pool.\n");
res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal 'auto' return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal 'auto' return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal 'auto'.\n");
res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
2);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal 'auto' with thread pool, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal 'auto' with thread pool, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal 'auto' with thread pool.\n");
#ifdef HAVE_POLL
@@ -1215,13 +1324,17 @@
0);
error_count += res;
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal poll, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal poll, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal poll.\n");
res = test_upgrade (MHD_USE_POLL_INTERNAL_THREAD,
2);
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal poll with thread pool, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal poll with thread pool, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal poll with thread pool.\n");
#endif
@@ -1229,13 +1342,17 @@
res = test_upgrade (MHD_USE_EPOLL_INTERNAL_THREAD,
0);
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal epoll, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal epoll, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal epoll.\n");
res = test_upgrade (MHD_USE_EPOLL_INTERNAL_THREAD,
2);
if (res)
- fprintf (stderr, "FAILED: Upgrade with internal epoll, return code %d.\n", res);
+ fprintf (stderr,
+ "FAILED: Upgrade with internal epoll, return code %d.\n",
+ res);
else if (verbose)
printf ("PASSED: Upgrade with internal epoll.\n");
#endif
@@ -1246,7 +1363,7 @@
error_count);
#ifdef HTTPS_SUPPORT
if (test_tls && (TLS_LIB_GNUTLS == use_tls_tool))
- gnutls_global_deinit();
+ gnutls_global_deinit ();
#endif /* HTTPS_SUPPORT */
return error_count != 0; /* 0 == pass */
}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/test_upgrade_large.c
^
|
@@ -0,0 +1,1571 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016, 2019 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_upgrade_large.c
+ * @brief Testcase for libmicrohttpd upgrading a connection,
+ * modified to test the "large" corner case reported
+ * by Viet on the mailinglist in 6'2019
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "mhd_options.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif /* HAVE_STDBOOL_H */
+
+#include "mhd_sockets.h"
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif /* HAVE_NETINET_IP_H */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include "mhd_itc.h"
+
+#include "test_helpers.h"
+
+#define LARGE_STRING \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelXloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello" \
+ "HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello\n"
+
+
+#define LARGE_REPLY_STRING \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld" \
+ "WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld\n"
+
+#ifdef HTTPS_SUPPORT
+#include <gnutls/gnutls.h>
+#include "../testcurl/https/tls_test_keys.h"
+
+#if defined(HAVE_FORK) && defined(HAVE_WAITPID)
+#include <sys/types.h>
+#include <sys/wait.h>
+#endif /* HAVE_FORK && HAVE_WAITPID */
+#endif /* HTTPS_SUPPORT */
+
+static int verbose = 0;
+
+static struct MHD_itc_ kicker = MHD_ITC_STATIC_INIT_INVALID;
+
+enum tls_tool
+{
+ TLS_CLI_NO_TOOL = 0,
+ TLS_CLI_GNUTLS,
+ TLS_CLI_OPENSSL,
+ TLS_LIB_GNUTLS
+};
+
+enum tls_tool use_tls_tool;
+
+#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
+/**
+ * Fork child that connects via GnuTLS-CLI to our @a port. Allows us to
+ * talk to our port over a socket in @a sp without having to worry
+ * about TLS.
+ *
+ * @param location where the socket is returned
+ * @return -1 on error, otherwise PID of TLS child process
+ */
+static pid_t
+gnutlscli_connect (int *sock,
+ uint16_t port)
+{
+ pid_t chld;
+ int sp[2];
+ char destination[30];
+
+ if (0 != socketpair (AF_UNIX,
+ SOCK_STREAM,
+ 0,
+ sp))
+ return -1;
+ chld = fork ();
+ if (0 != chld)
+ {
+ *sock = sp[1];
+ MHD_socket_close_chk_ (sp[0]);
+ return chld;
+ }
+ MHD_socket_close_chk_ (sp[1]);
+ (void) close (0);
+ (void) close (1);
+ if (-1 == dup2 (sp[0], 0))
+ abort ();
+ if (-1 == dup2 (sp[0], 1))
+ abort ();
+ MHD_socket_close_chk_ (sp[0]);
+ if (TLS_CLI_GNUTLS == use_tls_tool)
+ {
+ snprintf (destination,
+ sizeof(destination),
+ "%u",
+ (unsigned int) port);
+ execlp ("gnutls-cli",
+ "gnutls-cli",
+ "--insecure",
+ "-p",
+ destination,
+ "127.0.0.1",
+ (char *) NULL);
+ }
+ else if (TLS_CLI_OPENSSL == use_tls_tool)
+ {
+ snprintf (destination,
+ sizeof(destination),
+ "127.0.0.1:%u",
+ (unsigned int) port);
+ execlp ("openssl",
+ "openssl",
+ "s_client",
+ "-connect",
+ destination,
+ "-verify",
+ "1",
+ (char *) NULL);
+ }
+ _exit (1);
+}
+
+
+#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
+
+
+/**
+ * Wrapper structure for plain&TLS sockets
+ */
+struct wr_socket
+{
+ /**
+ * Real network socket
+ */
+ MHD_socket fd;
+
+ /**
+ * Type of this socket
+ */
+ enum wr_type
+ {
+ wr_invalid = 0,
+ wr_plain = 1,
+ wr_tls = 2
+ } t;
+#ifdef HTTPS_SUPPORT
+ /**
+ * TLS credentials
+ */
+ gnutls_certificate_credentials_t tls_crd;
+
+ /**
+ * TLS session.
+ */
+ gnutls_session_t tls_s;
+
+ /**
+ * TLS handshake already succeed?
+ */
+ bool tls_connected;
+#endif
+};
+
+
+/**
+ * Get underlying real socket.
+ * @return FD of real socket
+ */
+#define wr_fd(s) ((s)->fd)
+
+
+/**
+ * Create wr_socket with plain TCP underlying socket
+ * @return created socket on success, NULL otherwise
+ */
+static struct wr_socket *
+wr_create_plain_sckt (void)
+{
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+ if (NULL == s)
+ return NULL;
+ s->t = wr_plain;
+ s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (MHD_INVALID_SOCKET != s->fd)
+ return s;
+ free (s);
+ return NULL;
+}
+
+
+/**
+ * Create wr_socket with TLS TCP underlying socket
+ * @return created socket on success, NULL otherwise
+ */
+static struct wr_socket *
+wr_create_tls_sckt (void)
+{
+#ifdef HTTPS_SUPPORT
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+ if (NULL == s)
+ return NULL;
+ s->t = wr_tls;
+ s->tls_connected = 0;
+ s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (MHD_INVALID_SOCKET != s->fd)
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_init (&(s->tls_s), GNUTLS_CLIENT))
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_set_default_priority (s->tls_s))
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_certificate_allocate_credentials (
+ &(s->tls_crd)))
+ {
+ if (GNUTLS_E_SUCCESS == gnutls_credentials_set (s->tls_s,
+ GNUTLS_CRD_CERTIFICATE,
+ s->tls_crd))
+ {
+#if GNUTLS_VERSION_NUMBER + 0 >= 0x030109
+ gnutls_transport_set_int (s->tls_s, (int) (s->fd));
+#else /* GnuTLS before 3.1.9 */
+ gnutls_transport_set_ptr (s->tls_s,
+ (gnutls_transport_ptr_t) (intptr_t) (s->fd));
+#endif /* GnuTLS before 3.1.9 */
+ return s;
+ }
+ gnutls_certificate_free_credentials (s->tls_crd);
+ }
+ }
+ gnutls_deinit (s->tls_s);
+ }
+ (void) MHD_socket_close_ (s->fd);
+ }
+ free (s);
+#endif /* HTTPS_SUPPORT */
+ return NULL;
+}
+
+
+/**
+ * Create wr_socket with plain TCP underlying socket
+ * from already created TCP socket.
+ * @param plain_sk real TCP socket
+ * @return created socket on success, NULL otherwise
+ */
+static struct wr_socket *
+wr_create_from_plain_sckt (MHD_socket plain_sk)
+{
+ struct wr_socket *s = malloc (sizeof(struct wr_socket));
+
+ if (NULL == s)
+ return NULL;
+ s->t = wr_plain;
+ s->fd = plain_sk;
+ return s;
+}
+
+
+/**
+ * Connect socket to specified address.
+ * @param s socket to use
+ * @param addr address to connect
+ * @param length of structure pointed by @a addr
+ * @return zero on success, -1 otherwise.
+ */
+static int
+wr_connect (struct wr_socket *s,
+ const struct sockaddr *addr,
+ int length)
+{
+ if (0 != connect (s->fd, addr, length))
+ return -1;
+ if (wr_plain == s->t)
+ return 0;
+#ifdef HTTPS_SUPPORT
+ if (wr_tls == s->t)
+ {
+ /* Do not try handshake here as
+ * it require processing on MHD side and
+ * when testing with "external" polling,
+ * test will call MHD processing only
+ * after return from wr_connect(). */
+ s->tls_connected = 0;
+ return 0;
+ }
+#endif /* HTTPS_SUPPORT */
+ return -1;
+}
+
+
+#ifdef HTTPS_SUPPORT
+/* Only to be called from wr_send() and wr_recv() ! */
+static bool
+wr_handshake (struct wr_socket *s)
+{
+ int res = gnutls_handshake (s->tls_s);
+ if (GNUTLS_E_SUCCESS == res)
+ s->tls_connected = true;
+ else if (GNUTLS_E_AGAIN == res)
+ MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
+ else
+ MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
+ return s->tls_connected;
+}
+
+
+#endif /* HTTPS_SUPPORT */
+
+
+/**
+ * Send data to remote by socket.
+ *
+ * @param s the socket to use
+ * @param buf the buffer with data to send
+ * @param len the length of data in @a buf
+ * @return number of bytes were sent if succeed,
+ * -1 if failed. Use #MHD_socket_get_error_()
+ * to get socket error.
+ */
+static ssize_t
+wr_send (struct wr_socket *s,
+ const void *buf,
+ size_t len)
+{
+ if (wr_plain == s->t)
+ {
+ ssize_t ret;
+
+ ret = MHD_send_ (s->fd, buf, len);
+
+ return ret;
+ }
+#ifdef HTTPS_SUPPORT
+ if (wr_tls == s->t)
+ {
+ ssize_t ret;
+
+ if (! s->tls_connected && ! wr_handshake (s))
+ return -1;
+ ret = gnutls_record_send (s->tls_s,
+ buf,
+ len);
+ if (ret > 0)
+ return ret;
+ if (GNUTLS_E_AGAIN == ret)
+ MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
+ else
+ MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
+ }
+#endif /* HTTPS_SUPPORT */
+ return -1;
+}
+
+
+/**
+ * Receive data from remote by socket.
+ * @param s the socket to use
+ * @param buf the buffer to store received data
+ * @param len the length of @a buf
+ * @return number of bytes were received if succeed,
+ * -1 if failed. Use #MHD_socket_get_error_()
+ * to get socket error.
+ */
+static ssize_t
+wr_recv (struct wr_socket *s,
+ void *buf,
+ size_t len)
+{
+ if (wr_plain == s->t)
+ return MHD_recv_ (s->fd, buf, len);
+#ifdef HTTPS_SUPPORT
+ if (wr_tls == s->t)
+ {
+ ssize_t ret;
+ if (! s->tls_connected && ! wr_handshake (s))
+ return -1;
+
+ ret = gnutls_record_recv (s->tls_s, buf, len);
+ if (ret > 0)
+ return ret;
+ if (GNUTLS_E_AGAIN == ret)
+ MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
+ else
+ MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */
+ }
+#endif /* HTTPS_SUPPORT */
+ return -1;
+}
+
+
+/**
+ * Close socket and release allocated resourced
+ * @param s the socket to close
+ * @return zero on succeed, -1 otherwise
+ */
+static int
+wr_close (struct wr_socket *s)
+{
+ int ret = (MHD_socket_close_ (s->fd)) ? 0 : -1;
+#ifdef HTTPS_SUPPORT
+ if (wr_tls == s->t)
+ {
+ gnutls_deinit (s->tls_s);
+ gnutls_certificate_free_credentials (s->tls_crd);
+ }
+#endif /* HTTPS_SUPPORT */
+ free (s);
+ return ret;
+}
+
+
+/**
+ * Thread we use to run the interaction with the upgraded socket.
+ */
+static pthread_t pt;
+
+/**
+ * Will be set to the upgraded socket.
+ */
+static struct wr_socket *usock;
+
+/**
+ * Thread we use to run the interaction with the upgraded socket.
+ */
+static pthread_t pt_client;
+
+/**
+ * Flag set to 1 once the test is finished.
+ */
+static volatile bool done;
+
+
+/**
+ * Callback used by MHD to notify the application about completed
+ * requests. Frees memory.
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param con_cls value as set by the last call to
+ * the #MHD_AccessHandlerCallback
+ * @param toe reason for request termination
+ */
+static void
+notify_completed_cb (void *cls,
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
+{
+ pthread_t*ppth = *con_cls;
+
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
+ if ( (toe != MHD_REQUEST_TERMINATED_COMPLETED_OK) &&
+ (toe != MHD_REQUEST_TERMINATED_CLIENT_ABORT) &&
+ (toe != MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN) )
+ abort ();
+ if (! pthread_equal (**((pthread_t**) con_cls),
+ pthread_self ()))
+ abort ();
+ if (NULL != ppth)
+ free (*con_cls);
+ *con_cls = NULL;
+}
+
+
+/**
+ * Logging callback.
+ *
+ * @param cls logging closure (NULL)
+ * @param uri access URI
+ * @param connection connection handle
+ * @return #TEST_PTR
+ */
+static void *
+log_cb (void *cls,
+ const char *uri,
+ struct MHD_Connection *connection)
+{
+ pthread_t *ppth;
+
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
+ if (0 != strcmp (uri,
+ "/"))
+ abort ();
+ ppth = malloc (sizeof (pthread_t));
+ if (NULL == ppth)
+ abort ();
+ *ppth = pthread_self ();
+ return (void *) ppth;
+}
+
+
+/**
+ * Function to check that MHD properly notifies about starting
+ * and stopping.
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param socket_context socket-specific pointer where the
+ * client can associate some state specific
+ * to the TCP connection; note that this is
+ * different from the "con_cls" which is per
+ * HTTP request. The client can initialize
+ * during #MHD_CONNECTION_NOTIFY_STARTED and
+ * cleanup during #MHD_CONNECTION_NOTIFY_CLOSED
+ * and access in the meantime using
+ * #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+ * @param toe reason for connection notification
+ * @see #MHD_OPTION_NOTIFY_CONNECTION
+ * @ingroup request
+ */
+static void
+notify_connection_cb (void *cls,
+ struct MHD_Connection *connection,
+ void **socket_context,
+ enum MHD_ConnectionNotificationCode toe)
+{
+ static int started;
+
+ (void) cls;
+ (void) connection; /* Unused. Silent compiler warning. */
+ switch (toe)
+ {
+ case MHD_CONNECTION_NOTIFY_STARTED:
+ if (MHD_NO != started)
+ abort ();
+ started = MHD_YES;
+ *socket_context = &started;
+ break;
+ case MHD_CONNECTION_NOTIFY_CLOSED:
+ if (MHD_YES != started)
+ abort ();
+ if (&started != *socket_context)
+ abort ();
+ *socket_context = NULL;
+ started = MHD_NO;
+ break;
+ }
+}
+
+
+/**
+ * Change socket to blocking.
+ *
+ * @param fd the socket to manipulate
+ * @return non-zero if succeeded, zero otherwise
+ */
+static void
+make_blocking (MHD_socket fd)
+{
+#if defined(MHD_POSIX_SOCKETS)
+ int flags;
+
+ flags = fcntl (fd, F_GETFL);
+ if (-1 == flags)
+ return;
+ if ((flags & ~O_NONBLOCK) != flags)
+ if (-1 == fcntl (fd, F_SETFL, flags & ~O_NONBLOCK))
+ abort ();
+#elif defined(MHD_WINSOCK_SOCKETS)
+ unsigned long flags = 1;
+
+ ioctlsocket (fd, FIONBIO, &flags);
+#endif /* MHD_WINSOCK_SOCKETS */
+}
+
+
+static void
+kick_select ()
+{
+ if (MHD_ITC_IS_VALID_ (kicker))
+ {
+ (void) MHD_itc_activate_ (kicker, "K");
+ }
+}
+
+
+static void
+send_all (struct wr_socket *sock,
+ const char *text)
+{
+ size_t len = strlen (text);
+ ssize_t ret;
+ size_t off;
+
+ make_blocking (wr_fd (sock));
+ for (off = 0; off < len; off += ret)
+ {
+ ret = wr_send (sock,
+ &text[off],
+ len - off);
+ if (0 > ret)
+ {
+ if (! MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
+ abort ();
+ ret = 0;
+ }
+ kick_select ();
+ }
+}
+
+
+/**
+ * Read character-by-character until we
+ * get '\r\n\r\n'.
+ */
+static void
+recv_hdr (struct wr_socket *sock)
+{
+ unsigned int i;
+ char next;
+ char c;
+ ssize_t ret;
+
+ make_blocking (wr_fd (sock));
+ next = '\r';
+ i = 0;
+ while (i < 4)
+ {
+ ret = wr_recv (sock,
+ &c,
+ 1);
+ if (0 > ret)
+ {
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
+ continue;
+ fprintf (stderr,
+ "recv failed unexpectedly: %s\n",
+ MHD_socket_last_strerr_ ());
+ abort ();
+ }
+ if (0 == ret)
+ continue;
+ kick_select ();
+ if (c == next)
+ {
+ i++;
+ if (next == '\r')
+ next = '\n';
+ else
+ next = '\r';
+ continue;
+ }
+ if (c == '\r')
+ {
+ i = 1;
+ next = '\n';
+ continue;
+ }
+ i = 0;
+ next = '\r';
+ }
+}
+
+
+static void
+recv_all (struct wr_socket *sock,
+ const char *text)
+{
+ size_t len = strlen (text);
+ char buf[len];
+ ssize_t ret;
+ size_t off;
+
+ make_blocking (wr_fd (sock));
+ for (off = 0; off < len; off += ret)
+ {
+ ret = wr_recv (sock,
+ &buf[off],
+ len - off);
+ if (0 > ret)
+ {
+ if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
+ {
+ ret = 0;
+ continue;
+ }
+ abort ();
+ }
+ if (0 != strncmp (text, buf, off + ret))
+ abort ();
+ }
+ if (0 != strncmp (text, buf, len))
+ abort ();
+}
+
+
+/**
+ * Main function for the thread that runs the interaction with
+ * the upgraded socket.
+ *
+ * @param cls the handle for the upgrade
+ */
+static void *
+run_usock (void *cls)
+{
+ struct MHD_UpgradeResponseHandle *urh = cls;
+
+ send_all (usock,
+ LARGE_STRING);
+ recv_all (usock,
+ LARGE_REPLY_STRING);
+ send_all (usock,
+ "Finished");
+ MHD_upgrade_action (urh,
+ MHD_UPGRADE_ACTION_CLOSE);
+ free (usock);
+ usock = NULL;
+ return NULL;
+}
+
+
+/**
+ * Main function for the thread that runs the client-side of the
+ * interaction with the upgraded socket.
+ *
+ * @param cls the client socket
+ */
+static void *
+run_usock_client (void *cls)
+{
+ struct wr_socket *sock = cls;
+
+ send_all (sock,
+ "GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n");
+ recv_hdr (sock);
+ recv_all (sock,
+ LARGE_STRING);
+ send_all (sock,
+ LARGE_REPLY_STRING);
+ recv_all (sock,
+ "Finished");
+ wr_close (sock);
+ done = true;
+ return NULL;
+}
+
+
+/**
+ * Function called after a protocol "upgrade" response was sent
+ * successfully and the socket should now be controlled by some
+ * protocol other than HTTP.
+ *
+ * Any data already received on the socket will be made available in
+ * @e extra_in. This can happen if the application sent extra data
+ * before MHD send the upgrade response. The application should
+ * treat data from @a extra_in as if it had read it from the socket.
+ *
+ * Note that the application must not close() @a sock directly,
+ * but instead use #MHD_upgrade_action() for special operations
+ * on @a sock.
+ *
+ * Except when in 'thread-per-connection' mode, implementations
+ * of this function should never block (as it will still be called
+ * from within the main event loop).
+ *
+ * @param cls closure, whatever was given to #MHD_create_response_for_upgrade().
+ * @param connection original HTTP connection handle,
+ * giving the function a last chance
+ * to inspect the original HTTP request
+ * @param con_cls last value left in `con_cls` of the `MHD_AccessHandlerCallback`
+ * @param extra_in if we happened to have read bytes after the
+ * HTTP header already (because the client sent
+ * more than the HTTP header of the request before
+ * we sent the upgrade response),
+ * these are the extra bytes already read from @a sock
+ * by MHD. The application should treat these as if
+ * it had read them from @a sock.
+ * @param extra_in_size number of bytes in @a extra_in
+ * @param sock socket to use for bi-directional communication
+ * with the client. For HTTPS, this may not be a socket
+ * that is directly connected to the client and thus certain
+ * operations (TCP-specific setsockopt(), getsockopt(), etc.)
+ * may not work as expected (as the socket could be from a
+ * socketpair() or a TCP-loopback). The application is expected
+ * to perform read()/recv() and write()/send() calls on the socket.
+ * The application may also call shutdown(), but must not call
+ * close() directly.
+ * @param urh argument for #MHD_upgrade_action()s on this @a connection.
+ * Applications must eventually use this callback to (indirectly)
+ * perform the close() action on the @a sock.
+ */
+static void
+upgrade_cb (void *cls,
+ struct MHD_Connection *connection,
+ void *con_cls,
+ const char *extra_in,
+ size_t extra_in_size,
+ MHD_socket sock,
+ struct MHD_UpgradeResponseHandle *urh)
+{
+ (void) cls;
+ (void) connection;
+ (void) con_cls;
+ (void) extra_in; /* Unused. Silent compiler warning. */
+
+ usock = wr_create_from_plain_sckt (sock);
+ if (0 != extra_in_size)
+ abort ();
+ if (0 != pthread_create (&pt,
+ NULL,
+ &run_usock,
+ urh))
+ abort ();
+}
+
+
+/**
+ * A client has requested the given url using the given method
+ * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
+ * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc). The callback
+ * must call MHD callbacks to provide content to give back to the
+ * client and return an HTTP status code (i.e. #MHD_HTTP_OK,
+ * #MHD_HTTP_NOT_FOUND, etc.).
+ *
+ * @param cls argument given together with the function
+ * pointer when the handler was registered with MHD
+ * @param url the requested url
+ * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
+ * #MHD_HTTP_METHOD_PUT, etc.)
+ * @param version the HTTP version string (i.e.
+ * #MHD_HTTP_VERSION_1_1)
+ * @param upload_data the data being uploaded (excluding HEADERS,
+ * for a POST that fits into memory and that is encoded
+ * with a supported encoding, the POST data will NOT be
+ * given in upload_data and is instead available as
+ * part of #MHD_get_connection_values; very large POST
+ * data *will* be made available incrementally in
+ * @a upload_data)
+ * @param upload_data_size set initially to the size of the
+ * @a upload_data provided; the method must update this
+ * value to the number of bytes NOT processed;
+ * @param con_cls pointer that the callback can set to some
+ * address and that will be preserved by MHD for future
+ * calls for this request; since the access handler may
+ * be called many times (i.e., for a PUT/POST operation
+ * with plenty of upload data) this allows the application
+ * to easily associate some request-specific state.
+ * If necessary, this state can be cleaned up in the
+ * global #MHD_RequestCompletedCallback (which
+ * can be set with the #MHD_OPTION_NOTIFY_COMPLETED).
+ * Initially, `*con_cls` will be NULL.
+ * @return #MHD_YES if the connection was handled successfully,
+ * #MHD_NO if the socket must be closed due to a serious
+ * error while handling the request
+ */
+static enum MHD_Result
+ahc_upgrade (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls)
+{
+ struct MHD_Response *resp;
+ enum MHD_Result ret;
+ (void) cls;
+ (void) url;
+ (void) method; /* Unused. Silent compiler warning. */
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (NULL == *con_cls)
+ abort ();
+ if (! pthread_equal (**((pthread_t**) con_cls), pthread_self ()))
+ abort ();
+ resp = MHD_create_response_for_upgrade (&upgrade_cb,
+ NULL);
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_UPGRADE,
+ "Hello World Protocol");
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_SWITCHING_PROTOCOLS,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+}
+
+
+/**
+ * Run the MHD external event loop using select.
+ *
+ * @param daemon daemon to run it for
+ */
+static void
+run_mhd_select_loop (struct MHD_Daemon *daemon)
+{
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket max_fd;
+ MHD_UNSIGNED_LONG_LONG to;
+ struct timeval tv;
+
+ while (! done)
+ {
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ max_fd = -1;
+ to = 1000;
+
+ FD_SET (MHD_itc_r_fd_ (kicker), &rs);
+ if (MHD_YES !=
+ MHD_get_fdset (daemon,
+ &rs,
+ &ws,
+ &es,
+ &max_fd))
+ abort ();
+ (void) MHD_get_timeout (daemon,
+ &to);
+ if (1000 < to)
+ to = 1000;
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = 1000 * (to % 1000);
+ if (0 > MHD_SYS_select_ (max_fd + 1,
+ &rs,
+ &ws,
+ &es,
+ &tv))
+ abort ();
+ if (FD_ISSET (MHD_itc_r_fd_ (kicker), &rs))
+ MHD_itc_clear_ (kicker);
+ MHD_run_from_select (daemon,
+ &rs,
+ &ws,
+ &es);
+ }
+}
+
+
+#ifdef HAVE_POLL
+
+/**
+ * Run the MHD external event loop using select.
+ *
+ * @param daemon daemon to run it for
+ */
+static void
+run_mhd_poll_loop (struct MHD_Daemon *daemon)
+{
+ (void) daemon; /* Unused. Silent compiler warning. */
+ abort (); /* currently not implementable with existing MHD API */
+}
+
+
+#endif /* HAVE_POLL */
+
+
+#ifdef EPOLL_SUPPORT
+/**
+ * Run the MHD external event loop using select.
+ *
+ * @param daemon daemon to run it for
+ */
+static void
+run_mhd_epoll_loop (struct MHD_Daemon *daemon)
+{
+ const union MHD_DaemonInfo *di;
+ MHD_socket ep;
+ fd_set rs;
+ MHD_UNSIGNED_LONG_LONG to;
+ struct timeval tv;
+ int ret;
+
+ di = MHD_get_daemon_info (daemon,
+ MHD_DAEMON_INFO_EPOLL_FD);
+ ep = di->listen_fd;
+ while (! done)
+ {
+ FD_ZERO (&rs);
+ to = 1000;
+ FD_SET (MHD_itc_r_fd_ (kicker), &rs);
+ FD_SET (ep, &rs);
+ (void) MHD_get_timeout (daemon,
+ &to);
+ if (1000 < to)
+ to = 1000;
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = 1000 * (to % 1000);
+ ret = select (ep + 1,
+ &rs,
+ NULL,
+ NULL,
+ &tv);
+ if ( (-1 == ret) &&
+ (EAGAIN != errno) &&
+ (EINTR != errno) )
+ abort ();
+ if (FD_ISSET (MHD_itc_r_fd_ (kicker), &rs))
+ MHD_itc_clear_ (kicker);
+ MHD_run (daemon);
+ }
+}
+
+
+#endif /* EPOLL_SUPPORT */
+
+/**
+ * Run the MHD external event loop using select.
+ *
+ * @param daemon daemon to run it for
+ */
+static void
+run_mhd_loop (struct MHD_Daemon *daemon,
+ int flags)
+{
+ if (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL)))
+ run_mhd_select_loop (daemon);
+#ifdef HAVE_POLL
+ else if (0 != (flags & MHD_USE_POLL))
+ run_mhd_poll_loop (daemon);
+#endif /* HAVE_POLL */
+#if EPOLL_SUPPORT
+ else if (0 != (flags & MHD_USE_EPOLL))
+ run_mhd_epoll_loop (daemon);
+#endif
+ else
+ abort ();
+}
+
+
+static bool test_tls;
+
+/**
+ * Test upgrading a connection.
+ *
+ * @param flags which event loop style should be tested
+ * @param pool size of the thread pool, 0 to disable
+ */
+static int
+test_upgrade (int flags,
+ unsigned int pool)
+{
+ struct MHD_Daemon *d = NULL;
+ struct wr_socket *sock;
+ struct sockaddr_in sa;
+ const union MHD_DaemonInfo *real_flags;
+ const union MHD_DaemonInfo *dinfo;
+#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
+ pid_t pid = -1;
+#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
+
+ done = false;
+
+ if (! test_tls)
+ d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE,
+ MHD_is_feature_supported (
+ MHD_FEATURE_AUTODETECT_BIND_PORT) ?
+ 0 : 1090,
+ NULL, NULL,
+ &ahc_upgrade, NULL,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) 512,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb,
+ NULL,
+ MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb,
+ NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, pool,
+ MHD_OPTION_END);
+#ifdef HTTPS_SUPPORT
+ else
+ d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE
+ | MHD_USE_TLS,
+ MHD_is_feature_supported (
+ MHD_FEATURE_AUTODETECT_BIND_PORT) ?
+ 0 : 1090,
+ NULL, NULL,
+ &ahc_upgrade, NULL,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) 512,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, ¬ify_completed_cb,
+ NULL,
+ MHD_OPTION_NOTIFY_CONNECTION, ¬ify_connection_cb,
+ NULL,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
+ MHD_OPTION_THREAD_POOL_SIZE, pool,
+ MHD_OPTION_END);
+#endif /* HTTPS_SUPPORT */
+ if (NULL == d)
+ return 2;
+ real_flags = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_FLAGS);
+ if (NULL == real_flags)
+ abort ();
+ dinfo = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_BIND_PORT);
+ if ( (NULL == dinfo) ||
+ (0 == dinfo->port) )
+ abort ();
+ if (! test_tls || (TLS_LIB_GNUTLS == use_tls_tool))
+ {
+ sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt ();
+ if (NULL == sock)
+ abort ();
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons (dinfo->port);
+ sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (0 != wr_connect (sock,
+ (struct sockaddr *) &sa,
+ sizeof (sa)))
+ abort ();
+ }
+ else
+ {
+#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
+ MHD_socket tls_fork_sock;
+ uint16_t port;
+
+ /* make address sanitizer happy */
+ memcpy (&port,
+ dinfo /* ->port */,
+ sizeof (port));
+ if (-1 == (pid = gnutlscli_connect (&tls_fork_sock,
+ port)))
+ {
+ MHD_stop_daemon (d);
+ return 4;
+ }
+
+ sock = wr_create_from_plain_sckt (tls_fork_sock);
+ if (NULL == sock)
+ abort ();
+#else /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
+ abort ();
+#endif /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
+ }
+
+ if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
+ {
+ if (! MHD_itc_init_ (kicker))
+ abort ();
+ }
+
+ if (0 != pthread_create (&pt_client,
+ NULL,
+ &run_usock_client,
+ sock))
+ abort ();
+ if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
+ {
+ enum MHD_FLAG used_flags;
+
+ /* make address sanitizer happy */
+ memcpy (&used_flags,
+ real_flags /* ->flags */,
+ sizeof (used_flags));
+ run_mhd_loop (d, used_flags);
+ }
+ pthread_join (pt_client,
+ NULL);
+ pthread_join (pt,
+ NULL);
+#if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
+ if (test_tls && (TLS_LIB_GNUTLS != use_tls_tool))
+ waitpid (pid, NULL, 0);
+#endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */
+ if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
+ {
+ (void) MHD_itc_destroy_ (kicker);
+ MHD_itc_set_invalid_ (kicker);
+ }
+ MHD_stop_daemon (d);
+ return 0;
+}
+
+
+int
+main (int argc,
+ char *const *argv)
+{
+ int error_count = 0;
+ int res;
+
+ use_tls_tool = TLS_CLI_NO_TOOL;
+ test_tls = has_in_name (argv[0], "_tls");
+
+ verbose = 1;
+ if (has_param (argc, argv, "-q") ||
+ has_param (argc, argv, "--quiet"))
+ verbose = 0;
+ if (test_tls)
+ {
+#ifdef HTTPS_SUPPORT
+ if (has_param (argc, argv, "--use-gnutls-cli"))
+ use_tls_tool = TLS_CLI_GNUTLS;
+ else if (has_param (argc, argv, "--use-openssl"))
+ use_tls_tool = TLS_CLI_OPENSSL;
+ else if (has_param (argc, argv, "--use-gnutls-lib"))
+ use_tls_tool = TLS_LIB_GNUTLS;
+#if defined(HAVE_FORK) && defined(HAVE_WAITPID)
+ else if (0 == system ("gnutls-cli --version 1> /dev/null 2> /dev/null"))
+ use_tls_tool = TLS_CLI_GNUTLS;
+ else if (0 == system ("openssl version 1> /dev/null 2> /dev/null"))
+ use_tls_tool = TLS_CLI_OPENSSL;
+#endif /* HAVE_FORK && HAVE_WAITPID */
+ else
+ use_tls_tool = TLS_LIB_GNUTLS; /* Should be available as MHD use it. */
+ if (verbose)
+ {
+ switch (use_tls_tool)
+ {
+ case TLS_CLI_GNUTLS:
+ printf ("GnuTLS-CLI will be used for testing.\n");
+ break;
+ case TLS_CLI_OPENSSL:
+ printf ("Command line version of OpenSSL will be used for testing.\n");
+ break;
+ case TLS_LIB_GNUTLS:
+ printf ("GnuTLS library will be used for testing.\n");
+ break;
+ default:
+ abort ();
+ }
+ }
+ if ( (TLS_LIB_GNUTLS == use_tls_tool) &&
+ (GNUTLS_E_SUCCESS != gnutls_global_init ()) )
+ abort ();
+
+#else /* ! HTTPS_SUPPORT */
+ fprintf (stderr, "HTTPS support was disabled by configure.\n");
+ return 77;
+#endif /* ! HTTPS_SUPPORT */
+ }
+ /* run tests */
+ if (verbose)
+ printf ("Starting HTTP \"Upgrade\" tests with %s connections.\n",
+ test_tls ? "TLS" : "plain");
+ /* try external select */
+ res = test_upgrade (0,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with external select, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with external select.\n");
+ /* Try external auto */
+ res = test_upgrade (MHD_USE_AUTO,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with external 'auto', return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with external 'auto'.\n");
+
+#ifdef EPOLL_SUPPORT
+ res = test_upgrade (MHD_USE_EPOLL,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with external select with EPOLL, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with external select with EPOLL.\n");
+#endif
+
+ /* Test thread-per-connection */
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with thread per connection.\n");
+
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection and 'auto', return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with thread per connection and 'auto'.\n");
+#ifdef HAVE_POLL
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_POLL,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with thread per connection and poll, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with thread per connection and poll.\n");
+#endif /* HAVE_POLL */
+
+ /* Test different event loops, with and without thread pool */
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal select, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal select.\n");
+ res = test_upgrade (MHD_USE_INTERNAL_POLLING_THREAD,
+ 2);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal select with thread pool, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal select with thread pool.\n");
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal 'auto' return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal 'auto'.\n");
+ res = test_upgrade (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
+ 2);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal 'auto' with thread pool, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal 'auto' with thread pool.\n");
+#ifdef HAVE_POLL
+ res = test_upgrade (MHD_USE_POLL_INTERNAL_THREAD,
+ 0);
+ error_count += res;
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal poll, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal poll.\n");
+ res = test_upgrade (MHD_USE_POLL_INTERNAL_THREAD,
+ 2);
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal poll with thread pool, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal poll with thread pool.\n");
+#endif
+#ifdef EPOLL_SUPPORT
+ res = test_upgrade (MHD_USE_EPOLL_INTERNAL_THREAD,
+ 0);
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal epoll, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal epoll.\n");
+ res = test_upgrade (MHD_USE_EPOLL_INTERNAL_THREAD,
+ 2);
+ if (res)
+ fprintf (stderr,
+ "FAILED: Upgrade with internal epoll, return code %d.\n",
+ res);
+ else if (verbose)
+ printf ("PASSED: Upgrade with internal epoll.\n");
+#endif
+ /* report result */
+ if (0 != error_count)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ error_count);
+#ifdef HTTPS_SUPPORT
+ if (test_tls && (TLS_LIB_GNUTLS == use_tls_tool))
+ gnutls_global_deinit ();
+#endif /* HTTPS_SUPPORT */
+ return error_count != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/tsearch.c
^
|
@@ -13,7 +13,7 @@
#include <stdlib.h>
-typedef struct node
+typedef struct node
{
const void *key;
struct node *llink;
@@ -24,35 +24,35 @@
/* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */
/* find or insert datum into search tree */
void *
-tsearch (const void *vkey, /* key to be located */
- void **vrootp, /* address of tree root */
+tsearch (const void *vkey, /* key to be located */
+ void **vrootp, /* address of tree root */
int (*compar)(const void *, const void *))
{
node_t *q;
- node_t **rootp = (node_t **)vrootp;
+ node_t **rootp = (node_t **) vrootp;
if (NULL == rootp)
return NULL;
while (*rootp != NULL)
- { /* Knuth's T1: */
- int r;
+ { /* Knuth's T1: */
+ int r;
- if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
- return *rootp; /* we found it! */
+ if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
+ return *rootp; /* we found it! */
- rootp = (r < 0) ?
- &(*rootp)->llink : /* T3: follow left branch */
- &(*rootp)->rlink; /* T4: follow right branch */
- }
+ rootp = (r < 0) ?
+ &(*rootp)->llink : /* T3: follow left branch */
+ &(*rootp)->rlink; /* T4: follow right branch */
+ }
- q = malloc (sizeof(node_t)); /* T5: key not found */
+ q = malloc (sizeof(node_t)); /* T5: key not found */
if (q)
- { /* make new node */
- *rootp = q; /* link new node to old */
- q->key = vkey; /* initialize new node */
- q->llink = q->rlink = NULL;
- }
+ { /* make new node */
+ *rootp = q; /* link new node to old */
+ q->key = vkey; /* initialize new node */
+ q->llink = q->rlink = NULL;
+ }
return q;
}
@@ -61,24 +61,24 @@
/* find a node, or return NULL */
void *
tfind (const void *vkey, /* key to be found */
- void * const *vrootp, /* address of the tree root */
+ void *const *vrootp, /* address of the tree root */
int (*compar)(const void *, const void *))
{
- node_t * const *rootp = (node_t * const*)vrootp;
+ node_t *const *rootp = (node_t *const*) vrootp;
if (NULL == rootp)
return NULL;
while (*rootp != NULL)
- { /* T1: */
- int r;
+ { /* T1: */
+ int r;
- if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
- return *rootp; /* key found */
- rootp = (r < 0) ?
- &(*rootp)->llink : /* T3: follow left branch */
- &(*rootp)->rlink; /* T4: follow right branch */
- }
+ if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
+ return *rootp; /* key found */
+ rootp = (r < 0) ?
+ &(*rootp)->llink : /* T3: follow left branch */
+ &(*rootp)->rlink; /* T4: follow right branch */
+ }
return NULL;
}
@@ -92,52 +92,53 @@
* compar: function to carry out node comparisons
*/
void *
-tdelete (const void * __restrict vkey,
- void ** __restrict vrootp,
+tdelete (const void *__restrict vkey,
+ void **__restrict vrootp,
int (*compar)(const void *, const void *))
{
- node_t **rootp = (node_t **)vrootp;
+ node_t **rootp = (node_t **) vrootp;
node_t *p;
node_t *q;
node_t *r;
int cmp;
- if (rootp == NULL || (p = *rootp) == NULL)
+ if ((rootp == NULL) || ((p = *rootp) == NULL))
return NULL;
while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0)
- {
- p = *rootp;
- rootp = (cmp < 0) ?
- &(*rootp)->llink : /* follow llink branch */
- &(*rootp)->rlink; /* follow rlink branch */
- if (*rootp == NULL)
- return NULL; /* key not found */
- }
- r = (*rootp)->rlink; /* D1: */
- if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
- {
- q = r;
- }
+ {
+ p = *rootp;
+ rootp = (cmp < 0) ?
+ &(*rootp)->llink : /* follow llink branch */
+ &(*rootp)->rlink; /* follow rlink branch */
+ if (*rootp == NULL)
+ return NULL; /* key not found */
+ }
+ r = (*rootp)->rlink; /* D1: */
+ if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
+ {
+ q = r;
+ }
else if (r != NULL)
- { /* Right link is NULL? */
- if (r->llink == NULL)
- { /* D2: Find successor */
- r->llink = q;
- q = r;
- }
- else
- { /* D3: Find NULL link */
- for (q = r->llink; q->llink != NULL; q = r->llink)
- r = q;
- r->llink = q->rlink;
- q->llink = (*rootp)->llink;
- q->rlink = (*rootp)->rlink;
- }
+ { /* Right link is NULL? */
+ if (r->llink == NULL)
+ { /* D2: Find successor */
+ r->llink = q;
+ q = r;
}
- free(*rootp); /* D4: Free node */
- *rootp = q; /* link parent to new node */
+ else
+ { /* D3: Find NULL link */
+ for (q = r->llink; q->llink != NULL; q = r->llink)
+ r = q;
+ r->llink = q->rlink;
+ q->llink = (*rootp)->llink;
+ q->rlink = (*rootp)->rlink;
+ }
+ }
+ free (*rootp); /* D4: Free node */
+ *rootp = q; /* link parent to new node */
return p;
}
+
/* end of tsearch.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/microhttpd/tsearch.h
^
|
@@ -14,22 +14,22 @@
#endif /* __cplusplus */
-void *
-tdelete (const void * __restrict,
- void ** __restrict,
- int (*)(const void *, const void *));
+void *
+ tdelete (const void *__restrict,
+ void **__restrict,
+ int (*)(const void *, const void *));
-void *
-tfind (const void *,
- void * const *,
- int (*)(const void *, const void *));
+void *
+ tfind (const void *,
+ void *const *,
+ int (*)(const void *, const void *));
-void *
-tsearch (const void *,
- void **,
- int (*)(const void *, const void *));
+void *
+ tsearch (const void *,
+ void **,
+ int (*)(const void *, const void *));
#if defined(__cplusplus)
};
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/.gitignore
^
|
@@ -104,3 +104,19 @@
*.exe
test_quiesce_stream
test_large_put_inc11
+/test_deletetest_digestauth_sha256
+test_delete
+test_digestauth_sha256
+perf_get_concurrent11
+test_get_empty
+test_patch
+test_patch11
+/test_add_conn
+/test_add_conn_nolisten
+/test_add_conn_cleanup
+/test_add_conn_cleanup_nolisten
+core
+/test_get_iovec
+/test_get_iovec11
+/test_get_wait
+/test_get_wait11
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/Makefile.am
^
|
@@ -1,5 +1,7 @@
# This Makefile.am is in the public domain
-SUBDIRS = .
+EMPTY_ITEM =
+
+SUBDIRS = .
if USE_COVERAGE
AM_CFLAGS = -fprofile-arcs -ftest-coverage
@@ -10,54 +12,100 @@
endif
AM_CPPFLAGS = \
--DCPU_COUNT=$(CPU_COUNT) \
+-DMHD_CPU_COUNT=$(CPU_COUNT) \
-I$(top_srcdir) \
-I$(top_srcdir)/src/microhttpd \
-I$(top_srcdir)/src/include \
$(LIBCURL_CPPFLAGS)
+
+THREAD_ONLY_TESTS = \
+ test_urlparse \
+ test_long_header \
+ test_long_header11 \
+ test_iplimit11 \
+ test_termination \
+ $(EMPTY_ITEM)
+
+if HEAVY_TESTS
+THREAD_ONLY_TESTS += \
+ test_add_conn_cleanup \
+ test_add_conn_cleanup_nolisten \
+ $(EMPTY_ITEM)
+endif
+
+THREAD_ONLY_TESTS += \
+ test_timeout \
+ $(EMPTY_ITEM)
+
+if HAVE_POSIX_THREADS
+if HEAVY_TESTS
+THREAD_ONLY_TESTS += \
+ perf_get_concurrent11 \
+ $(EMPTY_ITEM)
+endif
+
+THREAD_ONLY_TESTS += \
+ test_get_wait \
+ test_get_wait11 \
+ test_quiesce \
+ $(EMPTY_ITEM)
+
+if HEAVY_TESTS
+THREAD_ONLY_TESTS += \
+ test_concurrent_stop \
+ $(EMPTY_ITEM)
+endif
+
+if HAVE_CURL_BINARY
+THREAD_ONLY_TESTS += \
+ test_quiesce_stream
+endif
+endif
+
+if ENABLE_DAUTH
+THREAD_ONLY_TESTS += \
+ test_digestauth \
+ test_digestauth_sha256 \
+ test_digestauth_with_arguments
+endif
+
+if HEAVY_TESTS
+if HAVE_POSIX_THREADS
+THREAD_ONLY_TESTS += \
+ perf_get_concurrent
+endif
+endif
+
if HAVE_CURL
check_PROGRAMS = \
- test_start_stop \
test_get \
+ test_get_iovec \
test_get_sendfile \
- test_urlparse \
test_delete \
+ test_patch \
test_put \
+ test_add_conn \
+ test_add_conn_nolisten \
test_process_headers \
test_process_arguments \
test_parse_cookies \
test_large_put \
test_get11 \
+ test_get_iovec11 \
test_get_sendfile11 \
+ test_patch11 \
test_put11 \
test_large_put11 \
test_large_put_inc11 \
- test_long_header \
- test_long_header11 \
test_get_chunked \
test_put_chunked \
- test_iplimit11 \
- test_termination \
- test_timeout \
test_callback \
- perf_get
-
-if HAVE_FORK_WAITPID
-if HAVE_CURL_BINARY
-check_PROGRAMS += test_get_response_cleanup
-endif
-endif
+ $(EMPTY_ITEM)
-if HAVE_POSIX_THREADS
+if HEAVY_TESTS
check_PROGRAMS += \
- test_quiesce \
- test_concurrent_stop \
- perf_get_concurrent
-
-if HAVE_CURL_BINARY
-check_PROGRAMS += test_quiesce_stream
-endif
+ perf_get
endif
if HAVE_POSTPROCESSOR
@@ -70,12 +118,21 @@
test_post_loop11
endif
-noinst_PROGRAMS = \
- test_options
+if HEAVY_TESTS
+if HAVE_FORK_WAITPID
+if HAVE_CURL_BINARY
+check_PROGRAMS += test_get_response_cleanup
+endif
+endif
+endif
-if ENABLE_DAUTH
- check_PROGRAMS += \
- test_digestauth test_digestauth_with_arguments
+if USE_POSIX_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
+endif
+if USE_W32_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
endif
TESTS = $(check_PROGRAMS)
@@ -86,11 +143,6 @@
libcurl_version_check_a_SOURCES = \
curl_version_check.c
-test_start_stop_SOURCES = \
- test_start_stop.c
-test_start_stop_LDADD = \
- $(top_builddir)/src/microhttpd/libmicrohttpd.la
-
test_concurrent_stop_SOURCES = \
test_concurrent_stop.c
test_concurrent_stop_CFLAGS = \
@@ -99,11 +151,6 @@
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
$(PTHREAD_LIBS) @LIBCURL@
-test_options_SOURCES = \
- test_options.c
-test_options_LDADD = \
- $(top_builddir)/src/microhttpd/libmicrohttpd.la
-
test_get_SOURCES = \
test_get.c
test_get_LDADD = \
@@ -134,46 +181,85 @@
perf_get_SOURCES = \
perf_get.c \
- gauger.h
+ gauger.h mhd_has_in_name.h
perf_get_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
perf_get_concurrent_SOURCES = \
perf_get_concurrent.c \
- gauger.h
+ gauger.h mhd_has_in_name.h
perf_get_concurrent_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
perf_get_concurrent_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
$(PTHREAD_LIBS) @LIBCURL@
+perf_get_concurrent11_SOURCES = \
+ perf_get_concurrent.c \
+ gauger.h mhd_has_in_name.h
+perf_get_concurrent11_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+perf_get_concurrent11_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS) @LIBCURL@
+
test_digestauth_SOURCES = \
test_digestauth.c
test_digestauth_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBGCRYPT_LIBS@ @LIBCURL@
+test_digestauth_sha256_SOURCES = \
+ test_digestauth_sha256.c
+test_digestauth_sha256_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBGCRYPT_LIBS@ @LIBCURL@
+
test_digestauth_with_arguments_SOURCES = \
test_digestauth_with_arguments.c
test_digestauth_with_arguments_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBGCRYPT_LIBS@ @LIBCURL@
+test_get_iovec_SOURCES = \
+ test_get_iovec.c mhd_has_in_name.h
+test_get_iovec_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
test_get_sendfile_SOURCES = \
- test_get_sendfile.c
+ test_get_sendfile.c mhd_has_in_name.h
test_get_sendfile_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_get_wait_SOURCES = \
+ test_get_wait.c \
+ mhd_has_in_name.h
+test_get_wait_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_get_wait_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS) @LIBCURL@
+
+test_get_wait11_SOURCES = \
+ test_get_wait.c \
+ mhd_has_in_name.h
+test_get_wait11_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_get_wait11_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS) @LIBCURL@
+
test_urlparse_SOURCES = \
- test_urlparse.c
+ test_urlparse.c mhd_has_in_name.h
test_urlparse_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_get_response_cleanup_SOURCES = \
- test_get_response_cleanup.c
+ test_get_response_cleanup.c mhd_has_in_name.h
test_get_response_cleanup_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la
@@ -184,49 +270,61 @@
@LIBCURL@
test_post_SOURCES = \
- test_post.c
+ test_post.c mhd_has_in_name.h
test_post_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_process_headers_SOURCES = \
- test_process_headers.c
+ test_process_headers.c mhd_has_in_name.h
test_process_headers_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_parse_cookies_SOURCES = \
- test_parse_cookies.c
+ test_parse_cookies.c mhd_has_in_name.h
test_parse_cookies_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_process_arguments_SOURCES = \
- test_process_arguments.c
+ test_process_arguments.c mhd_has_in_name.h
test_process_arguments_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_postform_SOURCES = \
- test_postform.c
+ test_postform.c mhd_has_in_name.h
test_postform_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBGCRYPT_LIBS@ @LIBCURL@
test_post_loop_SOURCES = \
- test_post_loop.c
+ test_post_loop.c mhd_has_in_name.h
test_post_loop_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_delete_SOURCES = \
- test_delete.c
+ test_delete.c mhd_has_in_name.h
test_delete_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_patch_SOURCES = \
+ test_patch.c mhd_has_in_name.h
+test_patch_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_patch11_SOURCES = \
+ test_patch.c mhd_has_in_name.h
+test_patch11_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
test_put_SOURCES = \
- test_put.c
+ test_put.c mhd_has_in_name.h
test_put_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
@@ -237,38 +335,76 @@
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_add_conn_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_add_conn_nolisten_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_nolisten_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_nolisten_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_add_conn_cleanup_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_cleanup_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_cleanup_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_add_conn_cleanup_nolisten_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_cleanup_nolisten_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_cleanup_nolisten_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
test_get11_SOURCES = \
test_get.c
test_get11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_get_iovec11_SOURCES = \
+ test_get_iovec.c mhd_has_in_name.h
+test_get_iovec11_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
test_get_sendfile11_SOURCES = \
- test_get_sendfile.c
+ test_get_sendfile.c mhd_has_in_name.h
test_get_sendfile11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_post11_SOURCES = \
- test_post.c
+ test_post.c mhd_has_in_name.h
test_post11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_postform11_SOURCES = \
- test_postform.c
+ test_postform.c mhd_has_in_name.h
test_postform11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBGCRYPT_LIBS@ @LIBCURL@
test_post_loop11_SOURCES = \
- test_post_loop.c
+ test_post_loop.c mhd_has_in_name.h
test_post_loop11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_put11_SOURCES = \
- test_put.c
+ test_put.c mhd_has_in_name.h
test_put11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
@@ -292,19 +428,19 @@
@LIBCURL@
test_long_header_SOURCES = \
- test_long_header.c
+ test_long_header.c mhd_has_in_name.h
test_long_header_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_long_header11_SOURCES = \
- test_long_header.c
+ test_long_header.c mhd_has_in_name.h
test_long_header11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_iplimit11_SOURCES = \
- test_iplimit.c
+ test_iplimit.c mhd_has_in_name.h
test_iplimit11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
@@ -316,7 +452,7 @@
@LIBCURL@
test_timeout_SOURCES = \
- test_timeout.c
+ test_timeout.c mhd_has_in_name.h
test_timeout_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/curl_version_check.c
^
|
@@ -39,21 +39,22 @@
char num[17];
while (i < 16 && ((**s >= '0') & (**s <= '9')))
- {
- num[i] = **s;
- (*s)++;
- i++;
- }
+ {
+ num[i] = **s;
+ (*s)++;
+ i++;
+ }
num[i] = '\0';
return atoi (num);
}
+
const char *
parse_version_string (const char *s, int *major, int *minor, int *micro)
{
- if (!s)
+ if (! s)
return NULL;
*major = parse_version_number (&s);
if (*s != '.')
@@ -67,12 +68,15 @@
return s;
}
+
#ifdef HTTPS_SUPPORT
int
-curl_uses_nss_ssl()
+curl_uses_nss_ssl ()
{
- return (strstr(curl_version(), " NSS/") != NULL) ? 0 : -1;
+ return (strstr (curl_version (), " NSS/") != NULL) ? 0 : -1;
}
+
+
#endif /* HTTPS_SUPPORT */
/*
@@ -105,23 +109,25 @@
return -1;
curl_ver++;
/* Parse version numbers */
- if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) ||
- (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor, &loc_micro)) )
+ if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor,
+ &rq_micro)) ||
+ (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor,
+ &loc_micro)) )
return -1;
/* Compare version numbers. */
- if ((loc_major > rq_major
- || (loc_major == rq_major && loc_minor > rq_minor)
- || (loc_major == rq_major && loc_minor == rq_minor
- && loc_micro > rq_micro) || (loc_major == rq_major
- && loc_minor == rq_minor
- && loc_micro == rq_micro)) == 0)
- {
- fprintf (stderr,
- "Error: running curl test depends on local libcurl version > %s\n",
- req_version);
- return -1;
- }
+ if (((loc_major > rq_major)
+ || ((loc_major == rq_major) && (loc_minor > rq_minor))
+ || ((loc_major == rq_major) && (loc_minor == rq_minor)
+ && (loc_micro > rq_micro)) || ((loc_major == rq_major)
+ && (loc_minor == rq_minor)
+ && (loc_micro == rq_micro) )) == 0)
+ {
+ fprintf (stderr,
+ "Error: running curl test depends on local libcurl version > %s\n",
+ req_version);
+ return -1;
+ }
/*
* enforce required gnutls/openssl version.
@@ -133,44 +139,46 @@
return -1;
ssl_ver++;
if (strncmp ("GnuTLS", ssl_ver, strlen ("GNUtls")) == 0)
- {
- ssl_ver = strchr (ssl_ver, '/');
- req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION;
- }
+ {
+ ssl_ver = strchr (ssl_ver, '/');
+ req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION;
+ }
else if (strncmp ("OpenSSL", ssl_ver, strlen ("OpenSSL")) == 0)
- {
- ssl_ver = strchr (ssl_ver, '/');
- req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION;
- }
+ {
+ ssl_ver = strchr (ssl_ver, '/');
+ req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION;
+ }
else if (strncmp ("NSS", ssl_ver, strlen ("NSS")) == 0)
- {
- ssl_ver = strchr (ssl_ver, '/');
- req_ssl_ver = MHD_REQ_CURL_NSS_VERSION;
- }
+ {
+ ssl_ver = strchr (ssl_ver, '/');
+ req_ssl_ver = MHD_REQ_CURL_NSS_VERSION;
+ }
else
- {
- fprintf (stderr, "Error: unrecognized curl ssl library\n");
- return -1;
- }
+ {
+ fprintf (stderr, "Error: unrecognized curl ssl library\n");
+ return -1;
+ }
if (ssl_ver == NULL)
return -1;
ssl_ver++;
- if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor, &rq_micro)) ||
- (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor, &loc_micro)) )
+ if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor,
+ &rq_micro)) ||
+ (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor,
+ &loc_micro)) )
return -1;
- if ((loc_major > rq_major
- || (loc_major == rq_major && loc_minor > rq_minor)
- || (loc_major == rq_major && loc_minor == rq_minor
- && loc_micro > rq_micro) || (loc_major == rq_major
- && loc_minor == rq_minor
- && loc_micro == rq_micro)) == 0)
- {
- fprintf (stderr,
- "Error: running curl test depends on local libcurl SSL version > %s\n",
- req_ssl_ver);
- return -1;
- }
+ if (((loc_major > rq_major)
+ || ((loc_major == rq_major) && (loc_minor > rq_minor))
+ || ((loc_major == rq_major) && (loc_minor == rq_minor)
+ && (loc_micro > rq_micro)) || ((loc_major == rq_major)
+ && (loc_minor == rq_minor)
+ && (loc_micro == rq_micro) )) == 0)
+ {
+ fprintf (stderr,
+ "Error: running curl test depends on local libcurl SSL version > %s\n",
+ req_ssl_ver);
+ return -1;
+ }
#endif /* HTTPS_SUPPORT */
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/gauger.h
^
|
@@ -17,70 +17,70 @@
#include <stdio.h>
#include <sys/wait.h>
-#define GAUGER(category, counter, value, unit)\
-{\
- const char * __gauger_v[10]; \
- char __gauger_s[32];\
- pid_t __gauger_p;\
- if(!(__gauger_p=fork())){\
- if(!fork()){ \
- sprintf(__gauger_s,"%Lf", (long double) (value));\
- __gauger_v[0] = "gauger";\
- __gauger_v[1] = "-n";\
- __gauger_v[2] = counter; \
- __gauger_v[3] = "-d";\
- __gauger_v[4] = __gauger_s;\
- __gauger_v[5] = "-u";\
- __gauger_v[6] = unit; \
- __gauger_v[7] = "-c";\
- __gauger_v[8] = category; \
- __gauger_v[9] = (char *)NULL;\
- execvp("gauger", (char*const*) __gauger_v); \
- _exit(1);\
- }else{\
- _exit(0);\
- }\
- }else{\
- waitpid(__gauger_p,NULL,0);\
- }\
-}
-
-#define GAUGER_ID(category, counter, value, unit, id)\
-{\
- char* __gauger_v[12];\
- char __gauger_s[32];\
- pid_t __gauger_p;\
- if(!(__gauger_p=fork())){\
- if(!fork()){\
- sprintf(__gauger_s,"%Lf", (long double) (value));\
- __gauger_v[0] = "gauger";\
- __gauger_v[1] = "-n";\
- __gauger_v[2] = counter;\
- __gauger_v[3] = "-d";\
- __gauger_v[4] = __gauger_s;\
- __gauger_v[5] = "-u";\
- __gauger_v[6] = unit;\
- __gauger_v[7] = "-i";\
- __gauger_v[8] = id;\
- __gauger_v[9] = "-c";\
- __gauger_v[10] = category;\
- __gauger_v[11] = (char *)NULL;\
- execvp("gauger",__gauger_v);\
- perror("gauger");\
- _exit(1);\
- }else{\
- _exit(0);\
- }\
- }else{\
- waitpid(__gauger_p,NULL,0);\
- }\
-}
+#define GAUGER(category, counter, value, unit) \
+ { \
+ const char *__gauger_v[10]; \
+ char __gauger_s[32]; \
+ pid_t __gauger_p; \
+ if (! (__gauger_p = fork ())) { \
+ if (! fork ()) { \
+ sprintf (__gauger_s,"%Lf", (long double) (value)); \
+ __gauger_v[0] = "gauger"; \
+ __gauger_v[1] = "-n"; \
+ __gauger_v[2] = counter; \
+ __gauger_v[3] = "-d"; \
+ __gauger_v[4] = __gauger_s; \
+ __gauger_v[5] = "-u"; \
+ __gauger_v[6] = unit; \
+ __gauger_v[7] = "-c"; \
+ __gauger_v[8] = category; \
+ __gauger_v[9] = (char *) NULL; \
+ execvp ("gauger", (char*const*) __gauger_v); \
+ _exit (1); \
+ }else{ \
+ _exit (0); \
+ } \
+ }else{ \
+ waitpid (__gauger_p,NULL,0); \
+ } \
+ }
+
+#define GAUGER_ID(category, counter, value, unit, id) \
+ { \
+ char*__gauger_v[12]; \
+ char __gauger_s[32]; \
+ pid_t __gauger_p; \
+ if (! (__gauger_p = fork ())) { \
+ if (! fork ()) { \
+ sprintf (__gauger_s,"%Lf", (long double) (value)); \
+ __gauger_v[0] = "gauger"; \
+ __gauger_v[1] = "-n"; \
+ __gauger_v[2] = counter; \
+ __gauger_v[3] = "-d"; \
+ __gauger_v[4] = __gauger_s; \
+ __gauger_v[5] = "-u"; \
+ __gauger_v[6] = unit; \
+ __gauger_v[7] = "-i"; \
+ __gauger_v[8] = id; \
+ __gauger_v[9] = "-c"; \
+ __gauger_v[10] = category; \
+ __gauger_v[11] = (char *) NULL; \
+ execvp ("gauger",__gauger_v); \
+ perror ("gauger"); \
+ _exit (1); \
+ }else{ \
+ _exit (0); \
+ } \
+ }else{ \
+ waitpid (__gauger_p,NULL,0); \
+ } \
+ }
#else
#define GAUGER_ID(category, counter, value, unit, id) {}
#define GAUGER(category, counter, value, unit) {}
-#endif // WINDOWS
+#endif /* WINDOWS */
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/.gitignore
^
|
@@ -53,4 +53,5 @@
/mhds_multi_daemon_test
/tls_authentication_test
/tmp_ca_cert.pem
+/test_https_get_iovec
*.exe
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/Makefile.am
^
|
@@ -1,4 +1,6 @@
# This Makefile.am is in the public domain
+EMPTY_ITEM =
+
SUBDIRS = .
if USE_COVERAGE
@@ -10,129 +12,169 @@
endif
if HAVE_POSIX_THREADS
- HTTPS_PARALLEL_TESTS = test_https_get_parallel \
- test_https_get_parallel_threads
+ HTTPS_PARALLEL_TESTS = \
+ test_https_get_parallel \
+ test_https_get_parallel_threads
endif
-CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT)
+.NOTPARALLEL:
+
+MHD_CPU_COUNT_DEF = -DMHD_CPU_COUNT=$(CPU_COUNT)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/include \
-I$(top_srcdir)/src/microhttpd \
-I$(top_srcdir)/src/platform \
- $(LIBCURL_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+ $(LIBCURL_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
-check_PROGRAMS = \
+THREAD_ONLY_TESTS = \
test_tls_options \
test_tls_authentication \
- test_https_multi_daemon \
- test_https_get \
- $(TEST_HTTPS_SNI) \
- test_https_get_select \
$(HTTPS_PARALLEL_TESTS) \
+ $(TEST_HTTPS_SNI) \
test_https_session_info \
test_https_time_out \
- test_empty_response
+ test_https_multi_daemon \
+ test_https_get \
+ test_empty_response \
+ test_https_get_iovec \
+ $(EMPTY_ITEM)
+
+check_PROGRAMS = \
+ test_https_get_select
+
+if USE_POSIX_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
+endif
+if USE_W32_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
+endif
+
+EXTRA_DIST = \
+ test-ca.crt test-ca.key \
+ host1.crt host1.key \
+ host2.crt host2.key
-EXTRA_DIST = cert.pem key.pem tls_test_keys.h tls_test_common.h \
- host1.crt host1.key host2.crt host2.key
TESTS = \
- test_tls_options \
- test_https_multi_daemon \
- test_https_get \
- $(TEST_HTTPS_SNI) \
- test_https_get_select \
- $(HTTPS_PARALLEL_TESTS) \
- test_https_session_info \
- test_https_time_out \
- test_tls_authentication \
- test_empty_response
+ $(check_PROGRAMS)
test_https_time_out_SOURCES = \
test_https_time_out.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_time_out_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_tls_options_SOURCES = \
test_tls_options.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_tls_options_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_https_get_parallel_SOURCES = \
test_https_get_parallel.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_get_parallel_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
test_https_get_parallel_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
test_https_get_parallel_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(PTHREAD_LIBS) $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_empty_response_SOURCES = \
test_empty_response.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_empty_response_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_https_get_parallel_threads_SOURCES = \
test_https_get_parallel_threads.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_get_parallel_threads_CPPFLAGS = \
- $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+ $(AM_CPPFLAGS) $(MHD_CPU_COUNT_DEF)
test_https_get_parallel_threads_CFLAGS = \
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
test_https_get_parallel_threads_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(PTHREAD_LIBS) $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_tls_authentication_SOURCES = \
test_tls_authentication.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_tls_authentication_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_https_session_info_SOURCES = \
test_https_session_info.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_session_info_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_https_multi_daemon_SOURCES = \
test_https_multi_daemon.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_multi_daemon_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
test_https_get_SOURCES = \
test_https_get.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_get_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_iovec_SOURCES = \
+ test_https_get_iovec.c \
+ tls_test_keys.h \
+ tls_test_common.h \
+ tls_test_common.c
+test_https_get_iovec_LDADD = \
+ $(top_builddir)/src/testcurl/libcurl_version_check.a \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
if HAVE_GNUTLS_SNI
test_https_sni_SOURCES = \
test_https_sni.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_sni_CPPFLAGS = \
$(AM_CPPFLAGS) \
@@ -140,14 +182,15 @@
test_https_sni_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
endif
test_https_get_select_SOURCES = \
test_https_get_select.c \
+ tls_test_keys.h \
+ tls_test_common.h \
tls_test_common.c
test_https_get_select_LDADD = \
$(top_builddir)/src/testcurl/libcurl_version_check.a \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
-
+ $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) @LIBGCRYPT_LIBS@ @LIBCURL@
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/host1.crt
^
|
@@ -1,15 +1,30 @@
-----BEGIN CERTIFICATE-----
-MIICWTCCAcICCQDc4McLp7j56DANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJa
-WjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMQ4wDAYDVQQDDAVob3N0MTEZMBcGCSqGSIb3DQEJARYKdGVzdEBo
-b3N0MTAgFw0xMzExMTcxNTE2MzdaGA8yMTEzMTAyNDE1MTYzN1owcDELMAkGA1UE
-BhMCWloxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
-ZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFaG9zdDExGTAXBgkqhkiG9w0BCQEWCnRl
-c3RAaG9zdDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKxYiRUzfQnekQn3
-6e+hP/mt/JEkiFzX5TV+E19ue2v4tc7lf+SoLEk2dVt5tGQkHjIGeFFNwCLrgXoi
-h3KfP4R1IYe7NFbM+lFVwPceF3inJ75dZD80BxaXQANeh0yC/DhaVJUFNaof2S4+
-7xd8zTL6M11gME+XmR8uaDvW7EBtAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAf62m
-Nstj9p9u8T5A5fRnJWfoglH/zfm7IHzht0Wi047O3NFZJ0pOPqV97HuErUA5oBGg
-qswnyRGyGMcvL08Bki7Q6NkY7K0ON3lq+ofTkIAHlOKMF+Y/otbjuIDHBfo63tmE
-uOcr8XDQGu9R0cfh+qLgicJQd/8cFBhxsL0ls6I=
+MIIFDjCCAvagAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MTAxMjM2MTZaGA8yMTIxMDMxNjEy
+MzYxNlowXDELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwG
+TW9zY293MRswGQYDVQQKDBJ0ZXN0LWxpYm1pY3JvaHR0cGQxDjAMBgNVBAMMBWhv
+c3QxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6yg4JZH7R2We2Wa0
+12TqU/6D/ur17TEGF2D5Mdn5neEk9fWe2coNvz9/CKgez39QaQKR5pUjtCt9QZNX
+4yenzulazMx7KhuI/rFPw0+BU1HnN+hUvmQZjbexl9E7u5QIfB2dD9UFUNhZRQHY
+I/UNd2nsVAMhKscoWcVQwNvO0tY3wYX88jrl4nKJlJdEMhKeHe0RMi6vdfZNx7Yi
+JsBMUEgj1wta9A+TLuMOqZnCktQR1nIAg7m4C3lWEZ/OWs0zGlNmwN81/A32+D4D
+ohCCLdyJsVcHmatEE8EmbjCSo9SVkOz/722UV8gvwlyhHa6c23a3t/dXjivCfK7+
+FiDskQIDAQABo4GyMIGvMAsGA1UdDwQEAwIFoDAMBgNVHRMBAf8EAjAAMBYGA1Ud
+JQEB/wQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQU3oKnON9eYczaV3TJKunbobf6
+uzAnBglghkgBhvhCAQ0EGhYYVGVzdCBsaWJtaWNyb2h0dHBkIGhvc3QxMBEGCWCG
+SAGG+EIBAQQEAwIGQDAfBgNVHSMEGDAWgBRYdUPApWoxw4U13Rqsjf9AHdbpLDAN
+BgkqhkiG9w0BAQsFAAOCAgEAKnzPKJ38JP30UE6bpwRy05Frnwt/0rX6B1a9a87M
+LOwjaqDQb8p1z22+xyqFYPfkvCqRuyEjyHdu7iMxmMgSlK9nT9NZVFHeM/+/E5p7
+cMngEwc/kLMwetaT1XFrb6zZ32Z61c56gprbGQhfLgvUocie4htv+ultMZtsTUx/
+YbwifcfO4aewwmq93YSxrNXIamSZdsBo/ET+eoouGAdPIeohXNxIJkjwLoN7MlKH
+9G+12N6DfJ+RJjoljfWuf9683VJzRYeVIJm8b/ZQ9sIeaVjbEM9vpwYVCX4GgfJV
+oEd+GFIj2NpLHYhnn757G7z9wmmc0KzutGhRoH8yQo5BHsxWBnxM64whCnvE6o88
+xPopbcJQrQdbrBxr7barMWUz9bPKcuSHVjya0G2ovlJ+gmXaug/FVOmNNG1Psqxe
+cwLuJYCjIk+ZElFRh3mo0UG0vJBF35wJSQZVEtJQ7sKutw6U+oU0r6yS/XsRhU4y
+p+/A23Z89haHB3phEBKZ923QIKmGofjjkXxMaGfp4FZKrGn7JmT4TQ7qjoSmJFPJ
+80a6HJbUK9rYjqdkxlMomJ2nCCcVdnzyj8apNx+cDkaIClmlUJROVuvmXJafQfml
+Pk3B3jzOn0slaqIQCkhyPi4v+7kYxG5plKhSgLwWaHx8ft6KrjXFDR920YSdOwPR
+OxY=
-----END CERTIFICATE-----
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/host1.key
^
|
@@ -1,15 +1,28 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQCsWIkVM30J3pEJ9+nvoT/5rfyRJIhc1+U1fhNfbntr+LXO5X/k
-qCxJNnVbebRkJB4yBnhRTcAi64F6Iodynz+EdSGHuzRWzPpRVcD3Hhd4pye+XWQ/
-NAcWl0ADXodMgvw4WlSVBTWqH9kuPu8XfM0y+jNdYDBPl5kfLmg71uxAbQIDAQAB
-AoGBAJvq9QmjLSnymtCj4pYSEai2iNpebKdiAlEkoC4j67DArupgohWhN398ryt0
-rYgzTMYBKHSVnI969AYkmtlNzM1yNckRQb/G/tWrkl9re28y2nbAExtHbvLoTk2C
-a/EEl1Op+JZNzLoSje7IQMVZoArD3d4aUbfux4XzlO2eRNmZAkEA2pV49QgcOTOJ
-PrR5cgekonNdeMtkbZm9dhxgDk9IsYkC0iOxjn/IbeCQN3wuTQ5/yLoiiQ/CQ8w5
-JndF/XpICwJBAMnY37BSRb+XKZeJWP0yjqyFJwzHXkh6IsoSF2OOXSixdiMpthLh
-IPzvo6Qxsnha4VvwuDxljHzQFPgMT//CTGcCQQDMs9S+LKU50JDEX4Goj43X8RBl
-cp0Poz3yYap3XDqowLYalADRgcvzUq3cuHgoA98Z3W9ASrjUg2o2ItcyBhV3AkAK
-bCBgwl7Hnc6P/I+Tw2CKl/WEO2cq5uOU+4opodg9maw39JdqMiW56cXRXJ+Sh17L
-mIpq0/OFHll21WvsEORRAkAnDDn/vmW25PSxPVY7tKKJCCkmtBeLQpySfpDgBF+O
-QvvokKs2COivc50rmOYNvD1WSsAOspdaSoZUgFw5ikti
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDrKDglkftHZZ7Z
+ZrTXZOpT/oP+6vXtMQYXYPkx2fmd4ST19Z7Zyg2/P38IqB7Pf1BpApHmlSO0K31B
+k1fjJ6fO6VrMzHsqG4j+sU/DT4FTUec36FS+ZBmNt7GX0Tu7lAh8HZ0P1QVQ2FlF
+Adgj9Q13aexUAyEqxyhZxVDA287S1jfBhfzyOuXicomUl0QyEp4d7REyLq919k3H
+tiImwExQSCPXC1r0D5Mu4w6pmcKS1BHWcgCDubgLeVYRn85azTMaU2bA3zX8Dfb4
+PgOiEIIt3ImxVweZq0QTwSZuMJKj1JWQ7P/vbZRXyC/CXKEdrpzbdre391eOK8J8
+rv4WIOyRAgMBAAECggEBAKAuu2BMOmB+BmCMp675XO1uN7eTkYXKmR2fvt+IXZJ/
+5M9uSpCMJCUcOYpKCwLI9JszVvM8sB9waFgc6Ach4hr9tg4/U75xFzZ2zaB7Ldr1
+tYzNw7wVL5rrgBusOQYjZkw1V+GK954EYXqyMOr9Z/jpvEPWBee/1eqgj8tvb0kJ
+uJgQUPNqPOcf72y71Z7jnHt4TZdQVwABgiPVYu+xKfK/UFB7pXhVpxQSD6n9G4O+
+7DUMw9FcOM01R55fr3lty3yNJjCwR8SGVSgqBAS9UkayaNCjjnghXG1RUdXUw8ox
+fNAh3JBnGAiv3ttmfBzpUBAcIFCF8dgrBTkLiJ98k+kCgYEA9nr1L+jKGXDn5h8C
+DaFH9Gn7Ww3vnJ2cNiKGu5NNoz09fpsWstaDVc8ePW7+wAvecFSx8Kc6rF7rxb1L
+UuoRrVfOs9G4pocvEgeAG16j2pr7CrTubmx9XRKy/blesZByerOliI5Iqo6OnZzX
+809dcxCQc5Le9GGVrokWGk1wxLMCgYEA9D1ODo+ZMNAEvvsqssVby6UfKDnjiZ3G
+1z0v0hSTt1qT/go82r1ilm7AljWFMtpNZ1As8aDVjjTLApMGDtKFhWb97whkKGoL
+GQSz4d7s2XbBP3naxw3qbUp+LomW9BvZ/B48Xy2mdvt+gJd3fgp5sG5DW5hnPwvN
+hc3cHJKa06sCgYAmAwJrGBCK6eGpmKCdb4EETY/pE/YfBiOAKcTzip0PjrM8IjjW
+7cQlaKK2QLbi8TGlyzoB7hhbWuwre6zxJY4CWKdVDgPXEsQMmMGF9wt3/Cy5Evwu
+ZWbUAr096eeTpL4y9B+UNrU4MHIIFpcrO9MimqxcVosxzxbhatzQw56fhwKBgQDB
+f/hhjN8fTw8Th8YyUC4Dz1Q5+HMOylOIn09Nr0PAliB9ufqwii6bZC9sUgavXUjJ
+uzmATZ4jxiu4ZGb+Q0fJgulYAVvosOsN7S3em1EmkPFVquLrpVi/Ma96i0NvLsmq
+9wF5np8t0N5OXrIqx33Vi+YNoVbbGiy//3KNqJDFdQKBgAFNQS3dFXSK/tKS59vY
+QvFI82x8SR/H+UTbfpGwfJomTVSGJFPT+YMrWBeiFeUCv+W6ZnniRjN3Ka5+9Gb8
+StvzBRex61NH1+K+06DthvdRMHMgD64mHx60ZUPbf1tzDC5vIgFTKjW42tSlYkdh
+uYkjXv3kGk8Wwk6I4lhcqOVu
+-----END PRIVATE KEY-----
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/host2.crt
^
|
@@ -1,15 +1,30 @@
-----BEGIN CERTIFICATE-----
-MIICWTCCAcICCQCJ9nhDYTUBKjANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJa
-WjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMQ4wDAYDVQQDDAVob3N0MjEZMBcGCSqGSIb3DQEJARYKdGVzdEBo
-b3N0MjAgFw0xMzExMTcxNTE2NDNaGA8yMTEzMTAyNDE1MTY0M1owcDELMAkGA1UE
-BhMCWloxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
-ZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFaG9zdDIxGTAXBgkqhkiG9w0BCQEWCnRl
-c3RAaG9zdDIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALVK8QKMvU96iNL2
-66PKm6xXw9NPHDn+o1TLF1CQRxXMrBYUrObk0961+3n3Z3BXOFHKfSV4E55CpVyz
-D1Wcadlt3B9z3ke3HOi0lEa1xNJTMQK/QT3Fx/NURmNg5s9HAsqY4ocb9KHaF5Ex
-0TgC0L0aRP0cK1x2TgPEHBNcgGl9AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAEXOi
-9rSmVrTN5olIdowctr1vWbGwRCjCnAFXDsqakcDASNthr15LB5kr/mrA3olJjbZh
-o+JDvWMY6FN8r1QXW0RL9/obbHxtJpwvAmYVMY9jrR8Rpo38p4RfXlN85g3q9PVx
-5IGLaOqLf4hSnKArFL/fzXwxX9b5HBCKlXfiuqM=
+MIIFDjCCAvagAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MTAxMjM2MTZaGA8yMTIxMDMxNjEy
+MzYxNlowXDELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwG
+TW9zY293MRswGQYDVQQKDBJ0ZXN0LWxpYm1pY3JvaHR0cGQxDjAMBgNVBAMMBWhv
+c3QyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSrwepZu2iycb2O+
+xTCUvSnljDwq7zlzaqyglWdT2fEPMft99OIoHy8P5nOXrYhDD82lGrbLyvw1WStf
+b25ZNAzezj6Pa2V2XVYyVU7B/lmjzumoOinZPACZdBI53d2kmWE+WsTOlDKjmvcT
+4eF/SEUMcmmAvp/sTEK2FE+mkMFN63C7B1jY1k8P5mjwTPOAL2/WU6I4H9HTDhPL
+f/bfIzFHqxKPwJJCRGXziEhz4ewNjkrPrXW9mm8c+SUmHispTxAm1JPnj3pmk7Yd
+Ju3XdIEjee+WH/WBt01u4gZpXq24cVWOB/FEziAKH6+ofgQVnHjdE/Uzu3PYLhwB
+eGcTOQIDAQABo4GyMIGvMAsGA1UdDwQEAwIFoDAMBgNVHRMBAf8EAjAAMBYGA1Ud
+JQEB/wQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBR3q5u0JT2i/LzBiY/sq4HwPvZA
+ijAnBglghkgBhvhCAQ0EGhYYVGVzdCBsaWJtaWNyb2h0dHBkIGhvc3QyMBEGCWCG
+SAGG+EIBAQQEAwIGQDAfBgNVHSMEGDAWgBRYdUPApWoxw4U13Rqsjf9AHdbpLDAN
+BgkqhkiG9w0BAQsFAAOCAgEA1NY3DjvAQXG1QN6qcbSaGXKlvbblB1jMJbmDvbL2
+eQD9fGNhzzVDZxFbj8u9BmhGh8SbfcrRj7vmK8/lyqWgJxEAjIOTF6l4fanT72vi
+ucSz93LXcHTBzkTdvZyfshdkWtHEssTSQ4WPj/WFwIbCPFZ+My1GEU6+v7AjlzM5
+ob9dTIW0kWbnTU20TR54c9+rzS03obLXuYXoSq+y8AonhvdEAdeRiWx4siXCUeMo
+lFNn8Lr7yMgFKo21G3EMUuWmw+VvS1MAXNIKauHywOTrdDtllVWZxsPhP9IpLazf
+lQFn5JkYMaioeVscWfMEVgycX6c2A0SKKNVc+z9XhjGHAWMjHkVKWhqWNtB3oT7m
+hBKeXRWqOPZj2Fxl0Nc7cF/w13moKkPTQb3GDFTS0tFo7CrDcGEupgXfzNXl5ztE
++09fh22D96PMtAYb6JTsXbI2xZ5fmLLAZHtIHz1KFdEmVG38CkvkzVtw6XDcEMRL
+mMuquyrw+3ug4oXDtT6mnlPr6MSEeP5bt4+sJhwyCYDmCkmF44K3rHm1cbaxsEtS
+P3jgYpjhgVBS75ZarpyZmj78usuDQwqPEGcW68RmdhvK89gajZKuqUcP0dl4TDPR
+CNGdTsd25O471k7ZEYkyaMWIIXjRzQwRQzMFsna/bewm79tpFI6Iji3mLH/o5jvA
+u6s=
-----END CERTIFICATE-----
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/host2.key
^
|
@@ -1,15 +1,28 @@
------BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQC1SvECjL1PeojS9uujypusV8PTTxw5/qNUyxdQkEcVzKwWFKzm
-5NPetft592dwVzhRyn0leBOeQqVcsw9VnGnZbdwfc95HtxzotJRGtcTSUzECv0E9
-xcfzVEZjYObPRwLKmOKHG/Sh2heRMdE4AtC9GkT9HCtcdk4DxBwTXIBpfQIDAQAB
-AoGAR5Do6TfDt69IefdNeCAQKg2PWUg+fUpfEacGciAyX5GnUSQiSReF58HxHumi
-ZL+ZlPgZRQRMwknO23Q4FnSjd66A3E9iHLqkWxRFJWME6E7zgtBrIjctnNu9uYM9
-cw4R6qmXOL7C5sK00KXF2ep8+s+JjrZz61o85QnGGRYA94ECQQDbG6f1B8NKY9T1
-1GDR/++rJbdTVQlZQcKSXMumpU6V3mEV0O9GkYaZzoYvWa3kx6c0np4karrm3QWa
-u5E0q1YdAkEA09FPcmzVvIR0+sMWca8QJ/tJUxD6qYo8vLOpO4wt4iTPhGBEU+Q5
-cgXmde3/plVsp0vYxK/NG5XZkoC1fbuC4QJATRGxRlLwsl3jLoUBeVxY5Q5jKYCj
-xS2ITwss5vUGa1jJNW9EesH9YmRudoFI1UwU2EFixtRz4Xik3ARV0vzhUQJAfabT
-50ASxqMYtczW2peMEPurMqCG4d4ES7iUMqPkcBuAErn8rntbbH19igWmOyi/rLp8
-m6jiFnQdPiAmCbEbYQJAFAKiQl2ZOe3gkSh8MaQilD8Ppog6rod4SQiSmRNsDWPi
-IxqXneaGDWhzynC9xr4SwuJ9D5VxW1phNyiveDuYXw==
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1KvB6lm7aLJxv
+Y77FMJS9KeWMPCrvOXNqrKCVZ1PZ8Q8x+3304igfLw/mc5etiEMPzaUatsvK/DVZ
+K19vblk0DN7OPo9rZXZdVjJVTsH+WaPO6ag6Kdk8AJl0Ejnd3aSZYT5axM6UMqOa
+9xPh4X9IRQxyaYC+n+xMQrYUT6aQwU3rcLsHWNjWTw/maPBM84Avb9ZTojgf0dMO
+E8t/9t8jMUerEo/AkkJEZfOISHPh7A2OSs+tdb2abxz5JSYeKylPECbUk+ePemaT
+th0m7dd0gSN575Yf9YG3TW7iBmlerbhxVY4H8UTOIAofr6h+BBWceN0T9TO7c9gu
+HAF4ZxM5AgMBAAECggEAfwfRwRM0PTTkp9I31MqAsLbs5szVihItlJHgs4HVMM8v
+SWu/YPMnEN6N9pf8tcgCxdT7POUJtpXrzk90Ro0IbU/M9q61H6fwO/gRqPFlYzR1
+gMMjm0z2rnT5JIMXIjOkk4u1Di5Lb2ymfSVcQpk8B2+rD5pclM1MAhkQ1OMYtww0
+f61bzbKr4sZ5gXgi5FWPY31NYbX/N3sgp02/JGioJuIz2nNwLXNu76vkLMX/bNuN
+Lo0fCzw4CBy8anV2er3lN6355nkT9VPiJIdxXxMB5DMXhYT8jX6giROc7/+KlWX9
+agGHI+7CyCc2RgxED/9rEY80fBoDHwHjRBKORe9QJQKBgQDsjakF+jo/zs2uXHpZ
+gPYwYjafOFrG7J/kZPWTgwS6+RA7A+ilzhKx3o4uDVVrDdYmlnRpgsu/czwkyVVi
+O/q6r65D4KndfBD7Yv1xwBaSZhj2VwozCNSXN/2TMBI/jlX8VkJKjFsXesKiOAYS
+Bzfa5Y9xz3gaTlL86oqTFoCgEwKBgQDED6vSeI1HADHBIstOdLlo0gFLkYT+3ZRT
+LgEY2fTDFTgxRFWMGxzF4MKnJ3OcJucfgbc/spIKvdUL7GSjDZQzprwhzSExzLqe
+H3LCwIk3Rzxii/ou0Nm97RX8zLVK2YPKY7yoTXF+hD0NoHxKQhPcF7z9ospOKRAb
+293Z2ophAwKBgQCgSCQ8zp3lWkT3XeXw+3bUtdd47wBjRTXZ1aaoOuBbqCMdObrL
+jeQQ7VG9Vn+IOCngn5VlYKCZqoUYD+tw0l9DW4Jir7mpP0VqcFp2Vsd0jwVe9P8O
+MW+Kvv9sWegjdFhC0Fe+l3epYx66N+e1E3r/MQiO/xrMCEIm6OzYWSjyTQKBgFIE
+nER32eIR2r6I57PycH3BHHmYbqKP3zTM0firdREHF3LEu2TZErhUxhlXD64LODSd
+9yLWePG1aCKMyazMSWsyHRGm1nQWyRrM3R1LnhtZ2ZEALbDX/b7OJ5yRpmWhiNhp
+0Mo3W3sppsDEmjoWWmiAJbeVGjyIQQzmdXBlU+4xAoGAE3Byb3HkcNmPcV/vANhE
+snsQMLqoVzBNgaLfnuYUgIOORBfCMXgrvojA+aiSZbQKgdEXl71avT/1Ny/VwVoc
+ODS+KMxfCNlGyQ2KuIxzWewxyBzdiXBFtQ7ArFwtmbY5kTuuglVzHbhCi9oE8foH
+QW5tpN+3bzftqWO3urbizGY=
+-----END PRIVATE KEY-----
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test-ca.crt
^
|
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGITCCBAmgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MThaGA8yMTIxMDMxNDE3
+MzYxOFowgYExCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMSEwHwYJKoZIhvcN
+AQkBFhJub2JvZHlAZXhhbXBsZS5vcmcxEDAOBgNVBAMMB3Rlc3QtQ0EwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDdaWupA4qZjCBNkJoJOm5xnCaizl36
+ZLUwp4xBL/YfXPWE3LkmAREiVI/YnAb8l6G7CJnz8dTsOJWkNXG6T1KVP5/2RvBI
+IaaaufRIAl7hEnj1j9E2hQlV2fxF2ZNhz+nqi0LqKV4LJSpclkXADf2FA9HsVRP/
+B7zYh+DP0fSU8V6bsu8XCeRGshroAPrc8rH8lFEEXpNLNIqQr8yKx6SmdB6hfja6
+6SQ0++qBhl0aJtn4LHWZohgjBmkIaGFPYIJLgxQ/xyp2Grz2q7lGKJ+zBkBF8iOP
+t3x+F1hSCBnr/DGYWmjEm5tYm+7pyuriPddXdCc8+qa2LxMZo3EXxLo5YISpPCyw
+Z7V3YAOZTr3m1C24LiYvPehCq1CTIkhhmqtlVJXU7ISD48cx9y+5Pi34wtbTI/gN
+x4voyTLAfyavKMmIpxxIRsWldiF2n06HdvCRVdihDQUad10ygTmWf1J/s2ZETAtH
+QaSd7MD389t6nQFtTIXigsNKnnDPlrtxt7rOLvLQeR0K04Gzrf/scheOanRAfOXH
+KNBFU7YkDFG8rqizlC65rx9qeXFYXQcHZTuqxK7tgZnSgJat3E70VbTSCsEEG7eR
+bNX/fChUKAIIpWaiW6HDlKLl6m2y+BzM91umBsKOqTvntMVFBSF9pVYlXK854aIR
+q8A2Xujd012seQIDAQABo4GfMIGcMAsGA1UdDwQEAwICpDASBgNVHRMBAf8ECDAG
+AQH/AgEBMB0GA1UdDgQWBBRYdUPApWoxw4U13Rqsjf9AHdbpLDATBgNVHSUEDDAK
+BggrBgEFBQcDATAkBglghkgBhvhCAQ0EFxYVVGVzdCBsaWJtaWNyb2h0dHBkIENB
+MB8GA1UdIwQYMBaAFFh1Q8ClajHDhTXdGqyN/0Ad1uksMA0GCSqGSIb3DQEBCwUA
+A4ICAQBvrrcTKVeI1EYnXo4BQD4oCvf9z1fYQmL21EbHwgjg1nmaPkvStgWAc5p1
+kKwySrpEMKXfu68X76RccXZyWWIamEjz2OCWYZgjX6d6FpjhLphL8WxXDy5C9eay
+ixN7+URz2XQoi22wqR+tCPDhrIzcMPyMkx/6gRgcYeDnaFrkdSeSsKsID4plfcIj
+ISWJDvv+IAgrtsG1NVHnGwpAv0od3A8/4/fR6PPyewaU3aydvjZ7Au8O9DGDjlU9
+9HdlOkkY6GVJ1pfGZib7cV7lhy0D2kj1g9xZh97YjpoUfppPl9r+6A8gDm0hXlAD
+TlzNYlwTb681ZEoSd9PiLEY8HETssHlays2dYXdcNwAEp69iIHz8q1Q98Be9LScl
+WEzgaOT9U7lpIw/MWbELoMsC+Ecs1cVWBIuiIq8aSG2kRr1x3S8yVXbAohAXif2s
+E6puieM/VJ25iaNhkbLmDkk58QVVmn9NZNv6ETxuSQMp9e0EwbVlj68vzClQ91Y/
+nmAiGcLFUEwB9G0szv9+vR+oDW4IkvdFZSUbcICd2cnynnwAD395onqS4hEZO1xM
+Gy5ZldbTMTjgn7fChNopz15ChPBnwFIjhm+S0CyiLRQAowfknRVq2IBkj7/5kOWg
+4mcxcq76HoQWK/8X/8RFL1eFVAvY7TNHYJ0RS51DMuwCNQictA==
+-----END CERTIFICATE-----
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test-ca.key
^
|
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEA3WlrqQOKmYwgTZCaCTpucZwmos5d+mS1MKeMQS/2H1z1hNy5
+JgERIlSP2JwG/JehuwiZ8/HU7DiVpDVxuk9SlT+f9kbwSCGmmrn0SAJe4RJ49Y/R
+NoUJVdn8RdmTYc/p6otC6ileCyUqXJZFwA39hQPR7FUT/we82Ifgz9H0lPFem7Lv
+FwnkRrIa6AD63PKx/JRRBF6TSzSKkK/MisekpnQeoX42uukkNPvqgYZdGibZ+Cx1
+maIYIwZpCGhhT2CCS4MUP8cqdhq89qu5RiifswZARfIjj7d8fhdYUggZ6/wxmFpo
+xJubWJvu6crq4j3XV3QnPPqmti8TGaNxF8S6OWCEqTwssGe1d2ADmU695tQtuC4m
+Lz3oQqtQkyJIYZqrZVSV1OyEg+PHMfcvuT4t+MLW0yP4DceL6MkywH8mryjJiKcc
+SEbFpXYhdp9Oh3bwkVXYoQ0FGnddMoE5ln9Sf7NmREwLR0GknezA9/Pbep0BbUyF
+4oLDSp5wz5a7cbe6zi7y0HkdCtOBs63/7HIXjmp0QHzlxyjQRVO2JAxRvK6os5Qu
+ua8fanlxWF0HB2U7qsSu7YGZ0oCWrdxO9FW00grBBBu3kWzV/3woVCgCCKVmoluh
+w5Si5eptsvgczPdbpgbCjqk757TFRQUhfaVWJVyvOeGiEavANl7o3dNdrHkCAwEA
+AQKCAgEA2nPJ4j75P9gOgxj5scMx9uve/uDnvkYgszmMW0DL8FPSdd0k3AdPdXTD
+XC9NgWjGDHhHFXXz44FMu3BzniPnUhQtalrBdhmlfKGeEHIuVJjaOUZFYCpQdKEX
+k39BN89gdqYiRlC8Vfi8XA90EDJ9gQCs3SVwDj7/JxChUcpQK6gd9TbNSQjcbpgJ
+jgBxgw/9Zjyb1tjNMPVNBcY95Gtn20dUdXfG3hFrRM+Mp3D/aO8OPhr3iLZyZBRO
+CxqZcCzDQWe50dda4J4u9J2ntj4cmxC+14Q5a/HYZbv4yy7tDHWOJUiGd/0jf4CS
+b59isgfb8JBMqpCPbc7yZGhrC81xAZdsw0jvDYgGUf86785983clipdCVJIKMqZm
+yjoo2DuSaivCGnaWUV1f+W2CgigpSXcDQ1/gDMt7xVoZNpfmdTgZzthUxXK3dFYO
+Jwem/ls6KD5THKpkHuA9BpnoksnpZqREK5FdMw8hCUpJEe1kXy4ZlQB91Ya74HQ0
+tgygL9BwEXDJ2vU14Onq8CH+Ul4kOzXnqMae35eKj1+/QI2PP1Wuk/vypSmrurfm
+3YLsnwm7OYSuWrAfFRmGTMhfny3v1xlw1ynmVBvxgQ2v2czxKGw8JG+9LoqbSB5O
+GP05Gpcys1CwR9Z2EjfExFNcWFIJQjwcZemlgHHwvHCBy1fz0AUCggEBAPSnznDv
+Wuj3gTkUDfNFTplsa8z3GIyrfBYDUyGJ51YiN5C2myGRcu60r5iMl4hxXC6mL4Cd
+5ew8LsXojPmC0sWZ2Cp+uhSH5FZaMNRumg4R8EA0Phwi0iBgDXM5318reMZF3BUr
+FSTn9a3nBkFpYMw1hxBlLj0o6S0TfZBmviTJUO7eiq6mAdO43l320Pw7E6xSWble
+QQaXzk2yGr2bV02heZcWfw+Fnui6xLruWZbVdvh+Q5KEJv90y9HcXm14LXiPRMBg
+zYvbW6tVZSQeXTs4wGC1RAZWZC7MG0XOoVj18WGx8hSZQND6awxFwHbItSlv05TX
+QkJ9ybZ7bcOQT78CggEBAOetsug2BQejAwRbbAsC078Vlr6PUspHmeT1Efp8ArFq
+rsmx2n2EoIcZSLkedZK1cXN7HMxVz1U0yx7k/OLIKlsfGNQdAQhCW875mbn0ET0c
+jUNpeJRXL6U5pwdPrsENyyAPsDyCsBT4ArGuEIFIxPlWtZTBzOAhJN9AwB5KW8g/
+zg1mwv1TCNNlQu3Ex46egI3cCUk+6b1BNwPuSKhuP+P22Vg+JBhIY+/iSJvgSRfP
+3LCNU0ds2D5xiwJNVwzVtrn3wIaYHj6S7lhfVGWdvQb8RsF9kyR06yJNTUyyybZ0
+pTHeRwNtbUoTeBUlwoBac6izNyGGguA42pDYmoAcEccCggEAfXgZrV1zWAqmoOki
+BmLC3nf2CRWn52yCpJ9r4MVieI/vwy2C/YIkWTsc2rUveW/5gIsFzYYsxixPKHwM
+4GExStmNPK3lLGZMueRjKm7WXuTgO20PdUp+TNA11aQWZC5dMAHfzpNbsqOrIVZb
+pOwwEkpZTBU303HJs65NNOMcHK2J7hb/NHY6daRXlgTgRJrfif5puWEXJBRyXvI6
+OIcUDOIFA3EsFH/IcT5nah6Wn342F1ZZvSg8/8GcTbIgUy/Q0gVXkvmSMGl8569R
+wWY5FggS0QXlLwLbOgy+59wCbycidaHWrq2xyfrDL3YOMFzaW7fX4HtMpeDws781
+GZhG7QKCAQEAhCfJTjzCUcDjD7E2yHEsaGvgOYN4Lnr5hmllgAUNZDb+zX7uq3rk
+NyxtF2wQlUd7F+y6WLT6OBiNZWop9xNHVgM/HoAM/rEbvc0Tq8dVrg6DZljbt4Kk
+YxOn+7uwa996ZyeL2HiUCOIQZ1prf9QKyFB19A042QEPD2rYLG8uO+RpnatovyiG
+eE/jBc6iJvCzVDiX83g3zQVOZKegOrPpLhi5kmSgIlno6AWkdYZTK4oe0XdMcgnc
+sIIEUaPcbC3ctehlomFTn04hN7fpZK2+DiYKFoWTUdB/8Gk4FvBFsBaJxRCOYZ4i
+IYdJkIahlKYEI89XO4CHV3AW/VkRiNJ6MQKCAQEAhosdYqtpJtdRJ3FWM4i6Miua
+OBEg7FU4JTH/0cekj0UMYFww3KK9c4KEdgVwRtsvLTZ++CXZ3XF9Er+6nPmC6nAo
+46b3Ow7rPzpm18jUNWMW0s+CZwKWkGe1sbek81L8SBCDRJKKhl6XgiPHGB/i8g65
+ZQv3B47BPflrjxJCQVADHpdW5vo0xY7xRr9zKYoAl4LQBTwLVMTP229iIcBFvRPp
+rs4KUecFQfEyXrJLwgQTl0uBItO86BWopCdh7T/0A7BjBk9jdklJNgml8Ctq+Yt9
+nqduIeW3c1aNqbNhn+IA27WW+tv+yzA4gNPS/OWr8J67HDGm4WSUAFGMLwmcSw==
+-----END RSA PRIVATE KEY-----
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_empty_response.c
^
|
@@ -20,7 +20,7 @@
/**
* @file test_empty_response.c
- * @brief Testcase for libmicrohttpd HTTPS GET operations with emtpy reply
+ * @brief Testcase for libmicrohttpd HTTPS GET operations with empty reply
* @author Christian Grothoff
*/
#include "platform.h"
@@ -28,17 +28,17 @@
#include <limits.h>
#include <sys/stat.h>
#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
extern const char srv_key_pem[];
extern const char srv_self_signed_cert_pem[];
-extern const char srv_signed_cert_pem[];
-extern const char srv_signed_key_pem[];
static int oneone;
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -48,10 +48,12 @@
void **unused)
{
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) url; (void) method; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
response = MHD_create_response_from_buffer (0, NULL,
- MHD_RESPMEM_PERSISTENT);
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -75,35 +77,53 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+ char *aes256_sha = "AES256-SHA";
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3000;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_TLS | MHD_USE_INTERNAL_POLLING_THREAD,
- 1082, NULL, NULL, &ahc_echo, "GET",
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_TLS
+ | MHD_USE_INTERNAL_POLLING_THREAD,
+ port, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
- MHD_OPTION_END);
+ MHD_OPTION_END);
if (d == NULL)
return 256;
- char *aes256_sha = "AES256-SHA";
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha = "rsa_aes_256_sha";
- }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha = "rsa_aes_256_sha";
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
/* TLS options */
curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
@@ -113,79 +133,88 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
mret = curl_multi_add_handle (multi, c);
if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 2048;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 != maxposixs)
{
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 != maxposixs)
- {
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
#ifdef MHD_POSIX_SOCKETS
- if (EINTR != errno)
-#endif /* MHD_POSIX_SOCKETS */
- abort ();
- }
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ }
+ else
+ (void) sleep (1);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ }
if (multi != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != 0)
return 8192;
@@ -197,18 +226,16 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
if (0 != (errorCount = testInternalSelectGet ()))
fprintf (stderr, "Failed test: %s, error: %u.\n", argv[0], errorCount);
curl_global_cleanup ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_get.c
^
|
@@ -29,69 +29,205 @@
#include <limits.h>
#include <sys/stat.h>
#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-extern const char srv_key_pem[];
-extern const char srv_self_signed_cert_pem[];
extern const char srv_signed_cert_pem[];
extern const char srv_signed_key_pem[];
+static int global_port;
+
+
+/* perform a HTTP GET request via SSL/TLS */
static int
-test_cipher_option (FILE * test_fd,
- const char *cipher_suite,
- int proto_version)
+test_secure_get (FILE *test_fd,
+ const char *cipher_suite,
+ int proto_version)
{
int ret;
struct MHD_Daemon *d;
+ int port;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, 4233,
- NULL, NULL, &http_ahc, NULL,
- MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
- MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3041;
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
+ NULL, NULL,
+ &http_ahc, NULL,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
MHD_OPTION_END);
if (d == NULL)
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (d); return -1;
}
+ port = (int) dinfo->port;
+ }
- ret = test_https_transfer (test_fd, cipher_suite, proto_version);
+ ret = test_https_transfer (test_fd,
+ port,
+ cipher_suite,
+ proto_version);
MHD_stop_daemon (d);
return ret;
}
-/* perform a HTTP GET request via SSL/TLS */
+static enum MHD_Result
+ahc_empty (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ (void) cls;
+ (void) url;
+ (void) url;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcasecmp ("GET",
+ method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ response = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (20);
+ }
+ return ret;
+}
+
+
static int
-test_secure_get (FILE * test_fd,
- const char *cipher_suite,
- int proto_version)
+curlExcessFound (CURL *c,
+ curl_infotype type,
+ char *data,
+ size_t size,
+ void *cls)
{
- int ret;
- struct MHD_Daemon *d;
+ static const char *excess_found = "Excess found";
+ const size_t str_size = strlen (excess_found);
+ (void) c; /* Unused. Silence compiler warning. */
+
+ if ((CURLINFO_TEXT == type)
+ && (size >= str_size)
+ && (0 == strncmp (excess_found, data, str_size)))
+ *(int *) cls = 1;
+ return 0;
+}
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, 4233,
- NULL, NULL, &http_ahc, NULL,
+
+static int
+testEmptyGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ int excess_found = 0;
+
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1225;
+
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag | MHD_USE_TLS,
+ global_port, NULL, NULL,
+ &ahc_empty, NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
MHD_OPTION_END);
-
if (d == NULL)
+ return 4194304;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (d); return 32;
}
-
- ret = test_https_transfer (test_fd, cipher_suite, proto_version);
-
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
+ curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 8388608;
+ }
+ curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return ret;
+ if (cbc.pos != 0)
+ return 16777216;
+ if (excess_found)
+ return 33554432;
+ return 0;
}
@@ -100,36 +236,30 @@
{
unsigned int errorCount = 0;
const char *aes256_sha_tlsv1 = "AES256-SHA";
- const char *des_cbc3_sha_tlsv1 = "DES-CBC3-SHA";
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
-
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha_tlsv1 = "rsa_aes_256_sha";
- des_cbc3_sha_tlsv1 = "rsa_aes_128_sha";
- }
-
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
+
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha_tlsv1 = "rsa_aes_256_sha";
+ }
errorCount +=
test_secure_get (NULL, aes256_sha_tlsv1, CURL_SSLVERSION_TLSv1);
- errorCount +=
- test_cipher_option (NULL, des_cbc3_sha_tlsv1, CURL_SSLVERSION_TLSv1);
- print_test_result (errorCount, argv[0]);
-
+ errorCount += testEmptyGet (0);
curl_global_cleanup ();
return errorCount != 0 ? 1 : 0;
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_get_iovec.c
^
|
@@ -0,0 +1,421 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2021 Christian Grothoff
+ Copyright (C) 2016-2021 Evgeny Grin
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_https_get_iovec.c
+ * @brief Testcase for libmicrohttpd HTTPS GET operations using an iovec
+ * @author Sagie Amir
+ * @author Karlson2k (Evgeny Grin)
+ * @author Lawrence Sebald
+ */
+
+/*
+ * This testcase is derived from the test_https_get.c testcase. This version
+ * adds the usage of a scatter/gather array for storing the response data.
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <limits.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+#include "tls_test_common.h"
+
+extern const char srv_signed_cert_pem[];
+extern const char srv_signed_key_pem[];
+
+
+static int global_port;
+
+/* Use large enough pieces (>16KB) to test partially consumed
+ * data as TLS doesn't take more than 16KB by a single call. */
+#define TESTSTR_IOVLEN 20480
+#define TESTSTR_IOVCNT 30
+#define TESTSTR_SIZE (TESTSTR_IOVCNT * TESTSTR_IOVLEN)
+
+
+static void
+iov_free_callback (void *cls)
+{
+ free (cls);
+}
+
+
+static int
+check_read_data (const void *ptr, size_t len)
+{
+ const int *buf;
+ size_t i;
+
+ if (len % sizeof(int))
+ return -1;
+
+ buf = (const int *) ptr;
+
+ for (i = 0; i < len / sizeof(int); ++i)
+ {
+ if (buf[i] != (int) i)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static enum MHD_Result
+iovec_ahc (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
+{
+ static int aptr;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ int *data;
+ struct MHD_IoVec iov[TESTSTR_IOVCNT];
+ int i;
+ int j;
+ (void) cls; (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+ return MHD_NO; /* unexpected method */
+ if (&aptr != *ptr)
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
+
+ /* Create some test data. */
+ if (NULL == (data = malloc (TESTSTR_SIZE)))
+ return MHD_NO;
+
+ for (j = 0; j < TESTSTR_IOVCNT; ++j)
+ {
+ /* Assign chunks of memory area in the reverse order
+ * to make non-continous set of data therefore
+ * possible buffer overruns could be detected */
+ iov[j].iov_base = data + (((TESTSTR_IOVCNT - 1) - j)
+ * (TESTSTR_SIZE / TESTSTR_IOVCNT
+ / sizeof(int)));
+ iov[j].iov_len = TESTSTR_SIZE / TESTSTR_IOVCNT;
+
+ for (i = 0; i < (int) (TESTSTR_IOVLEN / sizeof(int)); ++i)
+ ((int*) iov[j].iov_base)[i] = i + (j * TESTSTR_IOVLEN / sizeof(int));
+ }
+
+ response = MHD_create_response_from_iovec (iov,
+ TESTSTR_IOVCNT,
+ &iov_free_callback,
+ data);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+static int
+test_iovec_transfer (void *cls,
+ int port,
+ const char *cipher_suite,
+ int proto_version)
+{
+ int len;
+ int ret = 0;
+ struct CBC cbc;
+ char url[255];
+ (void) cls; /* Unused. Silent compiler warning. */
+
+ len = TESTSTR_SIZE;
+ if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
+ {
+ fprintf (stderr, MHD_E_MEM);
+ return -1;
+ }
+ cbc.size = len;
+ cbc.pos = 0;
+
+ if (gen_test_file_url (url,
+ sizeof (url),
+ port))
+ {
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (CURLE_OK !=
+ send_curl_req (url, &cbc, cipher_suite, proto_version))
+ {
+ ret = -1;
+ goto cleanup;
+ }
+
+ /* compare test file & daemon response */
+ if ((cbc.pos != TESTSTR_SIZE) ||
+ (0 != check_read_data (cbc.buf, cbc.pos)))
+ {
+ fprintf (stderr, "Error: local file & received file differ.\n");
+ ret = -1;
+ }
+cleanup:
+ free (cbc.buf);
+ return ret;
+}
+
+
+/* perform a HTTP GET request via SSL/TLS */
+static int
+test_secure_get (FILE *test_fd,
+ const char *cipher_suite,
+ int proto_version)
+{
+ int ret;
+ struct MHD_Daemon *d;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3041;
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
+ NULL, NULL,
+ &iovec_ahc, NULL,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
+ MHD_OPTION_END);
+
+ if (d == NULL)
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return -1;
+ }
+ port = (int) dinfo->port;
+ }
+
+ ret = test_iovec_transfer (test_fd,
+ port,
+ cipher_suite,
+ proto_version);
+
+ MHD_stop_daemon (d);
+ return ret;
+}
+
+
+static enum MHD_Result
+ahc_empty (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ struct MHD_IoVec iov;
+ (void) cls;
+ (void) url;
+ (void) url;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcasecmp ("GET",
+ method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+
+ iov.iov_base = NULL;
+ iov.iov_len = 0;
+
+ response = MHD_create_response_from_iovec (&iov,
+ 1,
+ NULL,
+ NULL);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (20);
+ }
+ return ret;
+}
+
+
+static int
+curlExcessFound (CURL *c,
+ curl_infotype type,
+ char *data,
+ size_t size,
+ void *cls)
+{
+ static const char *excess_found = "Excess found";
+ const size_t str_size = strlen (excess_found);
+ (void) c; /* Unused. Silence compiler warning. */
+
+ if ((CURLINFO_TEXT == type)
+ && (size >= str_size)
+ && (0 == strncmp (excess_found, data, str_size)))
+ *(int *) cls = 1;
+ return 0;
+}
+
+
+static int
+testEmptyGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ int excess_found = 0;
+
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1225;
+
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag | MHD_USE_TLS,
+ global_port, NULL, NULL,
+ &ahc_empty, NULL,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 4194304;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
+ curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 8388608;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 16777216;
+ if (excess_found)
+ return 33554432;
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ const char *aes256_sha_tlsv1 = "AES256-SHA";
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
+ if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
+
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha_tlsv1 = "rsa_aes_256_sha";
+ }
+ errorCount +=
+ test_secure_get (NULL, aes256_sha_tlsv1, CURL_SSLVERSION_TLSv1);
+ errorCount += testEmptyGet (0);
+ curl_global_cleanup ();
+
+ return errorCount != 0 ? 1 : 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_get_parallel.c
^
|
@@ -31,14 +31,16 @@
#include <limits.h>
#include <curl/curl.h>
#include <pthread.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 4
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 4
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 4
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 4
#endif
extern const char srv_key_pem[];
@@ -58,9 +60,9 @@
struct https_test_data *cargs = args;
int ret;
- /* time spread incomming requests */
+ /* time spread incoming requests */
usleep ((useconds_t) 10.0 * ((double) rand ()) / ((double) RAND_MAX));
- ret = test_https_transfer (NULL,
+ ret = test_https_transfer (NULL, cargs->port,
cargs->cipher_suite, cargs->proto_version);
if (ret == 0)
return NULL;
@@ -76,12 +78,13 @@
* TODO : make client_count a parameter - number of curl client threads to spawn
*/
static int
-test_single_client (void *cls, const char *cipher_suite,
+test_single_client (void *cls, int port, const char *cipher_suite,
int curl_proto_version)
{
void *client_thread_ret;
struct https_test_data client_args =
- { NULL, cipher_suite, curl_proto_version };
+ { NULL, port, cipher_suite, curl_proto_version };
+ (void) cls; /* Unused. Silent compiler warning. */
client_thread_ret = https_transfer_thread_adapter (&client_args);
if (client_thread_ret != NULL)
@@ -95,36 +98,37 @@
*
* @return: 0 upon all client requests returning '0', -1 otherwise.
*
- * TODO : make client_count a parameter - numver of curl client threads to spawn
+ * TODO : make client_count a parameter - number of curl client threads to spawn
*/
static int
-test_parallel_clients (void * cls, const char *cipher_suite,
+test_parallel_clients (void *cls, int port, const char *cipher_suite,
int curl_proto_version)
{
int i;
- int client_count = (CPU_COUNT - 1);
+ int client_count = (MHD_CPU_COUNT - 1);
void *client_thread_ret;
pthread_t client_arr[client_count];
struct https_test_data client_args =
- { NULL, cipher_suite, curl_proto_version };
+ { NULL, port, cipher_suite, curl_proto_version };
+ (void) cls; /* Unused. Silent compiler warning. */
for (i = 0; i < client_count; ++i)
+ {
+ if (pthread_create (&client_arr[i], NULL,
+ &https_transfer_thread_adapter, &client_args) != 0)
{
- if (pthread_create (&client_arr[i], NULL,
- &https_transfer_thread_adapter, &client_args) != 0)
- {
- fprintf (stderr, "Error: failed to spawn test client threads.\n");
- return -1;
- }
+ fprintf (stderr, "Error: failed to spawn test client threads.\n");
+ return -1;
}
+ }
/* check all client requests fulfilled correctly */
for (i = 0; i < client_count; ++i)
- {
- if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
- (client_thread_ret != NULL))
- return -1;
- }
+ {
+ if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
+ (client_thread_ret != NULL))
+ return -1;
+ }
return 0;
}
@@ -132,55 +136,65 @@
int
main (int argc, char *const *argv)
-{
+{
unsigned int errorCount = 0;
const char *aes256_sha = "AES256-SHA";
+ int port;
+ unsigned int iseed;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3020;
/* initialize random seed used by curl clients */
- unsigned int iseed = (unsigned int) time (NULL);
+ iseed = (unsigned int) time (NULL);
srand (iseed);
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- return 77;
- }
- if (curl_uses_nss_ssl() == 0)
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ return 77;
+ }
+ if (curl_uses_nss_ssl () == 0)
aes256_sha = "rsa_aes_256_sha";
#ifdef EPOLL_SUPPORT
errorCount +=
- test_wrap ("single threaded daemon, single client, epoll", &test_single_client,
- NULL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
+ test_wrap ("single threaded daemon, single client, epoll",
+ &test_single_client,
+ NULL, port,
+ MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
#endif
errorCount +=
test_wrap ("single threaded daemon, single client", &test_single_client,
- NULL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG,
+ NULL, port,
+ MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
#ifdef EPOLL_SUPPORT
errorCount +=
test_wrap ("single threaded daemon, parallel clients, epoll",
- &test_parallel_clients, NULL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
+ &test_parallel_clients, NULL, port,
+ MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
#endif
errorCount +=
test_wrap ("single threaded daemon, parallel clients",
- &test_parallel_clients, NULL,
- MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG,
+ &test_parallel_clients, NULL, port,
+ MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_get_parallel_threads.c
^
|
@@ -33,14 +33,16 @@
#include <limits.h>
#include <curl/curl.h>
#include <pthread.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 4
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 4
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 4
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 4
#endif
extern const char srv_key_pem[];
@@ -59,29 +61,31 @@
struct https_test_data *cargs = args;
int ret;
- /* time spread incomming requests */
+ /* time spread incoming requests */
usleep ((useconds_t) 10.0 * ((double) rand ()) / ((double) RAND_MAX));
- ret = test_https_transfer (cargs->cls,
+ ret = test_https_transfer (cargs->cls, cargs->port,
cargs->cipher_suite, cargs->proto_version);
if (ret == 0)
return NULL;
return &nonnull;
}
+
/**
* Test non-parallel requests.
*
* @return: 0 upon all client requests returning '0', -1 otherwise.
*
- * TODO : make client_count a parameter - numver of curl client threads to spawn
+ * TODO : make client_count a parameter - number of curl client threads to spawn
*/
static int
-test_single_client (void *cls, const char *cipher_suite,
+test_single_client (void *cls, int port, const char *cipher_suite,
int curl_proto_version)
{
void *client_thread_ret;
struct https_test_data client_args =
- { NULL, cipher_suite, curl_proto_version };
+ { NULL, port, cipher_suite, curl_proto_version };
+ (void) cls; /* Unused. Silent compiler warning. */
client_thread_ret = https_transfer_thread_adapter (&client_args);
if (client_thread_ret != NULL)
@@ -95,37 +99,38 @@
*
* @return: 0 upon all client requests returning '0', -1 otherwise.
*
- * TODO : make client_count a parameter - numver of curl client threads to spawn
+ * TODO : make client_count a parameter - number of curl client threads to spawn
*/
static int
-test_parallel_clients (void *cls, const char *cipher_suite,
+test_parallel_clients (void *cls, int port, const char *cipher_suite,
int curl_proto_version)
{
int i;
- int client_count = (CPU_COUNT - 1);
+ int client_count = (MHD_CPU_COUNT - 1);
void *client_thread_ret;
pthread_t client_arr[client_count];
struct https_test_data client_args =
- { NULL, cipher_suite, curl_proto_version };
+ { NULL, port, cipher_suite, curl_proto_version };
+ (void) cls; /* Unused. Silent compiler warning. */
for (i = 0; i < client_count; ++i)
+ {
+ if (pthread_create (&client_arr[i], NULL,
+ &https_transfer_thread_adapter, &client_args) != 0)
{
- if (pthread_create (&client_arr[i], NULL,
- &https_transfer_thread_adapter, &client_args) != 0)
- {
- fprintf (stderr, "Error: failed to spawn test client threads.\n");
+ fprintf (stderr, "Error: failed to spawn test client threads.\n");
- return -1;
- }
+ return -1;
}
+ }
/* check all client requests fulfilled correctly */
for (i = 0; i < client_count; ++i)
- {
- if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
- (client_thread_ret != NULL))
- return -1;
- }
+ {
+ if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
+ (client_thread_ret != NULL))
+ return -1;
+ }
return 0;
}
@@ -136,51 +141,60 @@
{
unsigned int errorCount = 0;
const char *ssl_version;
+ int port;
+ unsigned int iseed;
+ char *aes256_sha = "AES256-SHA";
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3010;
/* initialize random seed used by curl clients */
- unsigned int iseed = (unsigned int) time (NULL);
+ iseed = (unsigned int) time (NULL);
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
srand (iseed);
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+ if (! testsuite_curl_global_init ())
+ return 99;
ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
if (NULL == ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
if (0 != strncmp (ssl_version, "GnuTLS", 6))
- {
- fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
- curl_global_cleanup ();
- return 77;
- }
-
- char *aes256_sha = "AES256-SHA";
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha = "rsa_aes_256_sha";
- }
+ {
+ fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
+
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha = "rsa_aes_256_sha";
+ }
errorCount +=
test_wrap ("multi threaded daemon, single client", &test_single_client,
- NULL,
- MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
+ NULL, port,
+ MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
errorCount +=
test_wrap ("multi threaded daemon, parallel client",
- &test_parallel_clients, NULL,
- MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
+ &test_parallel_clients, NULL, port,
+ MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD,
aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
srv_self_signed_cert_pem, MHD_OPTION_END);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_get_select.c
^
|
@@ -29,17 +29,17 @@
#include <limits.h>
#include <sys/stat.h>
#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
extern const char srv_key_pem[];
extern const char srv_self_signed_cert_pem[];
-extern const char srv_signed_cert_pem[];
-extern const char srv_signed_key_pem[];
static int oneone;
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -51,19 +51,20 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -95,32 +96,49 @@
time_t start;
struct timeval tv;
const char *aes256_sha = "AES256-SHA";
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3030;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_TLS | flags,
- 1082, NULL, NULL, &ahc_echo, "GET",
+ port, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
- MHD_OPTION_END);
+ MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
- if (curl_uses_nss_ssl() == 0)
+ if (curl_uses_nss_ssl () == 0)
aes256_sha = "rsa_aes_256_sha";
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
/* TLS options */
curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
@@ -130,89 +148,98 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 != maxposixs)
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 != maxposixs)
- {
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
#ifdef MHD_POSIX_SOCKETS
- if (EINTR != errno)
-#endif /* MHD_POSIX_SOCKETS */
- abort ();
- }
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ }
+ else
+ (void) sleep (1);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
if (multi != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -226,18 +253,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+ oneone = 0;
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
#ifdef EPOLL_SUPPORT
errorCount += testExternalGet (MHD_USE_EPOLL);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_multi_daemon.c
^
|
@@ -29,10 +29,11 @@
#include <curl/curl.h>
#include <limits.h>
#include <sys/stat.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-extern int curl_check_version (const char *req_version, ...);
extern const char srv_key_pem[];
extern const char srv_self_signed_cert_pem[];
@@ -41,51 +42,85 @@
* doesn't affect the other
*/
static int
-test_concurent_daemon_pair (void *cls,
- const char *cipher_suite,
+test_concurent_daemon_pair (void *cls,
+ const char *cipher_suite,
int proto_version)
{
-
int ret;
struct MHD_Daemon *d1;
struct MHD_Daemon *d2;
+ int port1, port2;
+ (void) cls; /* Unused. Silent compiler warning. */
+
- d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT,
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port1 = port2 = 0;
+ else
+ {
+ port1 = 3050;
+ port2 = 3051;
+ }
+
+ d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port1,
NULL, NULL, &http_ahc, NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
MHD_OPTION_END);
if (d1 == NULL)
- {
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
- }
-
- d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT + 1,
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port1)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d1, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d1); return -1;
+ }
+ port1 = (int) dinfo->port;
+ }
+
+ d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port2,
NULL, NULL, &http_ahc, NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
MHD_OPTION_END);
if (d2 == NULL)
+ {
+ MHD_stop_daemon (d1);
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port2)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d2, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
MHD_stop_daemon (d1);
- fprintf (stderr, MHD_E_SERVER_INIT);
+ MHD_stop_daemon (d2);
return -1;
}
+ port2 = (int) dinfo->port;
+ }
ret =
- test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+ test_daemon_get (NULL, cipher_suite, proto_version, port1, 0);
ret +=
test_daemon_get (NULL, cipher_suite, proto_version,
- DEAMON_TEST_PORT + 1, 0);
+ port2, 0);
MHD_stop_daemon (d2);
ret +=
- test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+ test_daemon_get (NULL, cipher_suite, proto_version, port1, 0);
MHD_stop_daemon (d1);
return ret;
}
@@ -97,34 +132,33 @@
unsigned int errorCount = 0;
FILE *cert;
const char *aes256_sha = "AES256-SHA";
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error (code: %u). l:%d f:%s\n", errorCount, __LINE__,
- __FUNCTION__);
- return 99;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
if ((cert = setup_ca_cert ()) == NULL)
- {
- fprintf (stderr, MHD_E_TEST_FILE_CREAT);
- curl_global_cleanup ();
- return 99;
- }
-
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha = "rsa_aes_256_sha";
- }
+ {
+ fprintf (stderr, MHD_E_TEST_FILE_CREAT);
+ curl_global_cleanup ();
+ return 99;
+ }
+
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha = "rsa_aes_256_sha";
+ }
errorCount +=
test_concurent_daemon_pair (NULL, aes256_sha, CURL_SSLVERSION_TLSv1);
@@ -135,7 +169,7 @@
fclose (cert);
if (0 != remove (ca_cert_file_name))
fprintf (stderr,
- "Failed to remove `%s'\n",
- ca_cert_file_name);
+ "Failed to remove `%s'\n",
+ ca_cert_file_name);
return errorCount != 0 ? 1 : 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_session_info.c
^
|
@@ -27,10 +27,11 @@
#include "platform.h"
#include "microhttpd.h"
#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-extern int curl_check_version (const char *req_version, ...);
extern const char srv_key_pem[];
extern const char srv_self_signed_cert_pem[];
@@ -40,47 +41,50 @@
* HTTP access handler call back
* used to query negotiated security parameters
*/
-static int
+static enum MHD_Result
query_session_ahc (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
- const char *upload_data, const char *version,
+ const char *version, const char *upload_data,
size_t *upload_data_size, void **ptr)
{
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ int gret;
+ (void) cls; (void) url; (void) method; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (NULL == *ptr)
- {
- *ptr = &query_session_ahc;
- return MHD_YES;
- }
+ {
+ *ptr = (void*) &query_session_ahc;
+ return MHD_YES;
+ }
if (GNUTLS_TLS1_1 !=
- (ret = MHD_get_connection_info
- (connection,
- MHD_CONNECTION_INFO_PROTOCOL)->protocol))
+ (gret = MHD_get_connection_info
+ (connection,
+ MHD_CONNECTION_INFO_PROTOCOL)->protocol))
+ {
+ if (GNUTLS_TLS1_2 == gret)
{
- if (GNUTLS_TLS1_2 == ret)
- {
- /* as usual, TLS implementations sometimes don't
- quite do what was asked, just mildly complain... */
- fprintf (stderr,
- "Warning: requested TLS 1.1, got TLS 1.2\n");
- }
- else
- {
- /* really different version... */
- fprintf (stderr,
- "Error: requested protocol mismatch (wanted %d, got %d)\n",
- GNUTLS_TLS1_1,
- ret);
- return -1;
- }
+ /* as usual, TLS implementations sometimes don't
+ quite do what was asked, just mildly complain... */
+ fprintf (stderr,
+ "Warning: requested TLS 1.1, got TLS 1.2\n");
+ }
+ else
+ {
+ /* really different version... */
+ fprintf (stderr,
+ "Error: requested protocol mismatch (wanted %d, got %d)\n",
+ GNUTLS_TLS1_1,
+ gret);
+ return MHD_NO;
}
+ }
response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE),
- (void *) EMPTY_PAGE,
- MHD_RESPMEM_PERSISTENT);
+ (void *) EMPTY_PAGE,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -98,38 +102,58 @@
struct CBC cbc;
CURLcode errornum;
char url[256];
+ int port;
+ const char *aes256_sha = "AES256-SHA";
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3060;
if (NULL == (cbc.buf = malloc (sizeof (char) * 255)))
return 16;
cbc.size = 255;
cbc.pos = 0;
- gen_test_file_url (url, DEAMON_TEST_PORT);
-
/* setup test */
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
NULL, NULL, &query_session_ahc, NULL,
- MHD_OPTION_HTTPS_PRIORITIES, "NORMAL:+ARCFOUR-128",
+ MHD_OPTION_HTTPS_PRIORITIES, "NORMAL:+ARCFOUR-128",
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
MHD_OPTION_END);
if (d == NULL)
+ {
+ free (cbc.buf);
+ return 2;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
+ MHD_stop_daemon (d);
free (cbc.buf);
- return 2;
+ return 32;
}
+ port = (int) dinfo->port;
+ }
- const char *aes256_sha = "AES256-SHA";
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha = "rsa_aes_256_sha";
- }
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha = "rsa_aes_256_sha";
+ }
+ gen_test_file_url (url,
+ sizeof (url),
+ port);
c = curl_easy_init ();
#if DEBUG_HTTPS_TEST
- curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
#endif
curl_easy_setopt (c, CURLOPT_URL, url);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -141,47 +165,50 @@
curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
/* currently skip any peer authentication */
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
-
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr, "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
+ {
+ fprintf (stderr, "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
- MHD_stop_daemon (d);
- curl_easy_cleanup (c);
- free (cbc.buf);
- return -1;
- }
+ MHD_stop_daemon (d);
+ curl_easy_cleanup (c);
+ free (cbc.buf);
+ return -1;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
free (cbc.buf);
return 0;
}
+
+
#endif
int
main (int argc, char *const *argv)
{
+#if LIBCURL_VERSION_NUM >= 0x072200
unsigned int errorCount = 0;
const char *ssl_version;
+ (void) argc; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error (code: %u)\n", errorCount);
- return 99;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
if (NULL == ssl_version)
@@ -196,10 +223,11 @@
curl_global_cleanup ();
return 77;
}
-#if LIBCURL_VERSION_NUM >= 0x072200
errorCount += test_query_session ();
-#endif
print_test_result (errorCount, argv[0]);
curl_global_cleanup ();
return errorCount != 0 ? 1 : 0;
+#else /* LIBCURL_VERSION_NUM < 0x072200 */
+ return 77;
+#endif /* LIBCURL_VERSION_NUM < 0x072200 */
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_sni.c
^
|
@@ -28,7 +28,9 @@
#include <limits.h>
#include <sys/stat.h>
#include <curl/curl.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
#include <gnutls/gnutls.h>
@@ -58,9 +60,9 @@
* (This code is largely taken from GnuTLS).
*/
static void
-load_keys(const char *hostname,
- const char *CERT_FILE,
- const char *KEY_FILE)
+load_keys (const char *hostname,
+ const char *CERT_FILE,
+ const char *KEY_FILE)
{
int ret;
gnutls_datum_t data;
@@ -75,32 +77,32 @@
ret = gnutls_load_file (CERT_FILE, &data);
if (ret < 0)
- {
- fprintf (stderr,
- "*** Error loading certificate file %s.\n",
- CERT_FILE);
- exit (1);
- }
+ {
+ fprintf (stderr,
+ "*** Error loading certificate file %s.\n",
+ CERT_FILE);
+ exit (1);
+ }
ret =
gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM,
0);
if (ret < 0)
- {
- fprintf (stderr,
- "*** Error loading certificate file: %s\n",
- gnutls_strerror (ret));
- exit (1);
- }
+ {
+ fprintf (stderr,
+ "*** Error loading certificate file: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
gnutls_free (data.data);
ret = gnutls_load_file (KEY_FILE, &data);
if (ret < 0)
- {
- fprintf (stderr,
- "*** Error loading key file %s.\n",
- KEY_FILE);
- exit (1);
- }
+ {
+ fprintf (stderr,
+ "*** Error loading key file %s.\n",
+ KEY_FILE);
+ exit (1);
+ }
gnutls_privkey_init (&host->key);
ret =
@@ -108,17 +110,16 @@
&data, GNUTLS_X509_FMT_PEM,
NULL, 0);
if (ret < 0)
- {
- fprintf (stderr,
- "*** Error loading key file: %s\n",
- gnutls_strerror (ret));
- exit (1);
- }
+ {
+ fprintf (stderr,
+ "*** Error loading key file: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
gnutls_free (data.data);
}
-
/**
* @param session the session we are giving a cert for
* @param req_ca_dn NULL on server side
@@ -131,18 +132,19 @@
*/
static int
sni_callback (gnutls_session_t session,
- const gnutls_datum_t* req_ca_dn,
+ const gnutls_datum_t*req_ca_dn,
int nreqs,
- const gnutls_pk_algorithm_t* pk_algos,
+ const gnutls_pk_algorithm_t*pk_algos,
int pk_algos_length,
- gnutls_pcert_st** pcert,
+ gnutls_pcert_st**pcert,
unsigned int *pcert_length,
- gnutls_privkey_t * pkey)
+ gnutls_privkey_t *pkey)
{
char name[256];
size_t name_len;
struct Hosts *host;
unsigned int type;
+ (void) req_ca_dn; (void) nreqs; (void) pk_algos; (void) pk_algos_length; /* Unused. Silent compiler warning. */
name_len = sizeof (name);
if (GNUTLS_E_SUCCESS !=
@@ -156,13 +158,13 @@
if (0 == strncmp (name, host->hostname, name_len))
break;
if (NULL == host)
- {
- fprintf (stderr,
- "Need certificate for %.*s\n",
- (int) name_len,
- name);
- return -1;
- }
+ {
+ fprintf (stderr,
+ "Need certificate for %.*s\n",
+ (int) name_len,
+ name);
+ return -1;
+ }
#if 0
fprintf (stderr,
"Returning certificate for %.*s\n",
@@ -178,28 +180,30 @@
/* perform a HTTP GET request via SSL/TLS */
static int
-do_get (const char *url)
+do_get (const char *url, int port)
{
CURL *c;
struct CBC cbc;
CURLcode errornum;
size_t len;
struct curl_slist *dns_info;
+ char buf[256];
len = strlen (test_data);
if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
- {
- fprintf (stderr, MHD_E_MEM);
- return -1;
- }
+ {
+ fprintf (stderr, MHD_E_MEM);
+ return -1;
+ }
cbc.size = len;
cbc.pos = 0;
c = curl_easy_init ();
#if DEBUG_HTTPS_TEST
- curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
#endif
curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
@@ -208,35 +212,37 @@
/* perform peer authentication */
/* TODO merge into send_curl_req */
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 2);
- dns_info = curl_slist_append (NULL, "host1:4233:127.0.0.1");
- dns_info = curl_slist_append (dns_info, "host2:4233:127.0.0.1");
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 2L);
+ sprintf (buf, "host1:%d:127.0.0.1", port);
+ dns_info = curl_slist_append (NULL, buf);
+ sprintf (buf, "host2:%d:127.0.0.1", port);
+ dns_info = curl_slist_append (dns_info, buf);
curl_easy_setopt (c, CURLOPT_RESOLVE, dns_info);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr, "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- free (cbc.buf);
- curl_slist_free_all (dns_info);
- return errornum;
- }
+ {
+ fprintf (stderr, "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ free (cbc.buf);
+ curl_slist_free_all (dns_info);
+ return errornum;
+ }
curl_easy_cleanup (c);
curl_slist_free_all (dns_info);
if (memcmp (cbc.buf, test_data, len) != 0)
- {
- fprintf (stderr, "Error: local file & received file differ.\n");
- free (cbc.buf);
- return -1;
- }
+ {
+ fprintf (stderr, "Error: local file & received file differ.\n");
+ free (cbc.buf);
+ return -1;
+ }
free (cbc.buf);
return 0;
@@ -248,39 +254,57 @@
{
unsigned int error_count = 0;
struct MHD_Daemon *d;
+ int port;
+ (void) argc; /* Unused. Silent compiler warning. */
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3060;
+
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
load_keys ("host1", ABS_SRCDIR "/host1.crt", ABS_SRCDIR "/host1.key");
load_keys ("host2", ABS_SRCDIR "/host2.crt", ABS_SRCDIR "/host2.key");
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG,
- 4233,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG,
+ port,
NULL, NULL,
&http_ahc, NULL,
MHD_OPTION_HTTPS_CERT_CALLBACK, &sni_callback,
MHD_OPTION_END);
if (d == NULL)
- {
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
- }
- if (0 != do_get ("https://host1:4233/"))
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return -1;
+ }
+ port = (int) dinfo->port;
+ }
+ if (0 != do_get ("https://host1/", port))
error_count++;
- if (0 != do_get ("https://host2:4233/"))
+ if (0 != do_get ("https://host2/", port))
error_count++;
MHD_stop_daemon (d);
@@ -293,10 +317,13 @@
#else
-int main ()
+int
+main (void)
{
fprintf (stderr,
"SNI not supported by GnuTLS < 3.0\n");
return 77;
}
+
+
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_https_time_out.c
^
|
@@ -28,7 +28,9 @@
#include "platform.h"
#include "microhttpd.h"
#include "tls_test_common.h"
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "mhd_sockets.h" /* only macros used */
@@ -45,22 +47,22 @@
static const int TIME_OUT = 3;
static int
-test_tls_session_time_out (gnutls_session_t session)
+test_tls_session_time_out (gnutls_session_t session, int port)
{
int ret;
MHD_socket sd;
struct sockaddr_in sa;
sd = socket (AF_INET, SOCK_STREAM, 0);
- if (sd == -1)
- {
- fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
- return -1;
- }
+ if (sd == MHD_INVALID_SOCKET)
+ {
+ fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
+ return -1;
+ }
memset (&sa, '\0', sizeof (struct sockaddr_in));
sa.sin_family = AF_INET;
- sa.sin_port = htons (DEAMON_TEST_PORT);
+ sa.sin_port = htons (port);
sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd);
@@ -68,30 +70,30 @@
ret = connect (sd, (struct sockaddr *) &sa, sizeof (struct sockaddr_in));
if (ret < 0)
- {
- fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT);
- MHD_socket_close_chk_ (sd);
- return -1;
- }
+ {
+ fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT);
+ MHD_socket_close_chk_ (sd);
+ return -1;
+ }
ret = gnutls_handshake (session);
if (ret < 0)
- {
- fprintf (stderr, "Handshake failed\n");
- MHD_socket_close_chk_ (sd);
- return -1;
- }
+ {
+ fprintf (stderr, "Handshake failed\n");
+ MHD_socket_close_chk_ (sd);
+ return -1;
+ }
- sleep (TIME_OUT + 1);
+ (void) sleep (TIME_OUT + 1);
/* check that server has closed the connection */
/* TODO better RST trigger */
if (send (sd, "", 1, 0) == 0)
- {
- fprintf (stderr, "Connection failed to time-out\n");
- MHD_socket_close_chk_ (sd);
- return -1;
- }
+ {
+ fprintf (stderr, "Connection failed to time-out\n");
+ MHD_socket_close_chk_ (sd);
+ return -1;
+ }
MHD_socket_close_chk_ (sd);
return 0;
@@ -101,23 +103,32 @@
int
main (int argc, char *const *argv)
{
- int errorCount = 0;;
+ int errorCount = 0;
struct MHD_Daemon *d;
gnutls_session_t session;
gnutls_datum_t key;
gnutls_datum_t cert;
gnutls_certificate_credentials_t xcred;
+ int port;
+ (void) argc; /* Unused. Silent compiler warning. */
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3070;
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
gnutls_global_init ();
gnutls_global_set_log_level (11);
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
NULL, NULL, &http_dummy_ahc, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT,
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
@@ -125,17 +136,27 @@
MHD_OPTION_END);
if (NULL == d)
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (d); return -1;
}
+ port = (int) dinfo->port;
+ }
if (0 != setup_session (&session, &key, &cert, &xcred))
- {
- fprintf (stderr, "failed to setup session\n");
- return 1;
- }
- errorCount += test_tls_session_time_out (session);
+ {
+ fprintf (stderr, "failed to setup session\n");
+ return 1;
+ }
+ errorCount += test_tls_session_time_out (session, port);
teardown_session (session, &key, &cert, xcred);
print_test_result (errorCount, argv[0]);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_tls_authentication.c
^
|
@@ -29,40 +29,54 @@
#include <curl/curl.h>
#include <limits.h>
#include <sys/stat.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
-extern int curl_check_version (const char *req_version, ...);
-extern const char test_file_data[];
-
-extern const char ca_key_pem[];
-extern const char ca_cert_pem[];
extern const char srv_signed_cert_pem[];
extern const char srv_signed_key_pem[];
-
/* perform a HTTP GET request via SSL/TLS */
static int
-test_secure_get (void * cls, char *cipher_suite, int proto_version)
+test_secure_get (void *cls, char *cipher_suite, int proto_version)
{
int ret;
struct MHD_Daemon *d;
+ int port;
+ (void) cls; /* Unused. Silent compiler warning. */
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT,
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3070;
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
NULL, NULL, &http_ahc, NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
MHD_OPTION_END);
if (d == NULL)
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (d); return -1;
}
+ port = (int) dinfo->port;
+ }
- ret = test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+ ret = test_daemon_get (NULL, cipher_suite, proto_version, port, 0);
MHD_stop_daemon (d);
return ret;
@@ -74,34 +88,36 @@
{
unsigned int errorCount = 0;
char *aes256_sha = "AES256-SHA";
+ FILE *crt;
+ (void) argc;
+ (void) argv; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error (code: %u)\n", errorCount);
- return 99;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (! testsuite_curl_global_init ())
+ return 99;
if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
- {
- fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
- curl_global_cleanup ();
- return 77;
- }
-
- if (setup_ca_cert () == NULL)
- {
- fprintf (stderr, MHD_E_TEST_FILE_CREAT);
- curl_global_cleanup ();
- return 99;
- }
-
- if (curl_uses_nss_ssl() == 0)
- {
- aes256_sha = "rsa_aes_256_sha";
- }
+ {
+ fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n");
+ curl_global_cleanup ();
+ return 77;
+ }
+
+ if (NULL == (crt = setup_ca_cert ()))
+ {
+ fprintf (stderr, MHD_E_TEST_FILE_CREAT);
+ curl_global_cleanup ();
+ return 99;
+ }
+ fclose (crt);
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes256_sha = "rsa_aes_256_sha";
+ }
errorCount +=
test_secure_get (NULL, aes256_sha, CURL_SSLVERSION_TLSv1);
@@ -111,7 +127,7 @@
curl_global_cleanup ();
if (0 != remove (ca_cert_file_name))
fprintf (stderr,
- "Failed to remove `%s'\n",
- ca_cert_file_name);
+ "Failed to remove `%s'\n",
+ ca_cert_file_name);
return errorCount != 0 ? 1 : 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_tls_extensions.c
^
|
@@ -29,6 +29,9 @@
#include "microhttpd.h"
#include "tls_test_common.h"
#include "mhd_sockets.h" /* only macros used */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#define MAX_EXT_DATA_LENGTH 256
@@ -39,13 +42,14 @@
* Test daemon response to TLS client hello requests containing extensions
*
* @param session
+ * @param port
* @param exten_t - the type of extension being appended to client hello request
* @param ext_count - the number of consecutive extension replicas inserted into request
* @param ext_length - the length of each appended extension
* @return 0 on successful test completion, -1 otherwise
*/
static int
-test_hello_extension (gnutls_session_t session, extensions_t exten_t,
+test_hello_extension (gnutls_session_t session, int port, extensions_t exten_t,
int ext_count, int ext_length)
{
int i, ret = 0, pos = 0;
@@ -65,23 +69,23 @@
sd = -1;
memset (&cbc, 0, sizeof (struct CBC));
if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
- {
- fprintf (stderr, MHD_E_MEM);
- ret = -1;
- goto cleanup;
- }
+ {
+ fprintf (stderr, MHD_E_MEM);
+ ret = -1;
+ goto cleanup;
+ }
cbc.size = 256;
sd = socket (AF_INET, SOCK_STREAM, 0);
if (sd == -1)
- {
- fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
- free (cbc.buf);
- return -1;
- }
+ {
+ fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
+ free (cbc.buf);
+ return -1;
+ }
memset (&sa, '\0', sizeof (struct sockaddr_in));
sa.sin_family = AF_INET;
- sa.sin_port = htons (DEAMON_TEST_PORT);
+ sa.sin_port = htons (port);
sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
enum MHD_GNUTLS_Protocol hver;
@@ -97,10 +101,10 @@
data = MHD_gnutls_malloc (datalen);
if (data == NULL)
- {
- free (cbc.buf);
- return -1;
- }
+ {
+ free (cbc.buf);
+ return -1;
+ }
hver = MHD_gtls_version_max (session);
data[pos++] = MHD_gtls_version_get_major (hver);
data[pos++] = MHD_gtls_version_get_minor (hver);
@@ -115,7 +119,8 @@
/* generate session client random */
memset (session->security_parameters.client_random, 0, TLS_RANDOM_SIZE);
gnutls_write_uint32 (time (NULL), rnd);
- if (GC_OK != MHD_gc_nonce ((char *) &rnd[4], TLS_RANDOM_SIZE - 4)) abort ();
+ if (GC_OK != MHD_gc_nonce ((char *) &rnd[4], TLS_RANDOM_SIZE - 4))
+ abort ();
memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE);
memcpy (&data[pos], rnd, TLS_RANDOM_SIZE);
pos += TLS_RANDOM_SIZE;
@@ -127,8 +132,7 @@
* len = ciphersuite data + 2 bytes ciphersuite length \
* 1 byte compression length + 1 byte compression data + \
* 2 bytes extension length, extensions data
- */
- ciphersuite_len = MHD__gnutls_copy_ciphersuites (session, extdata,
+ */ciphersuite_len = MHD__gnutls_copy_ciphersuites (session, extdata,
sizeof (extdata));
exten_data_len = ext_count * (2 + 2 + ext_length);
datalen += ciphersuite_len + 2 + 2 + exten_data_len;
@@ -144,35 +148,37 @@
gnutls_write_uint16 (exten_data_len, &data[pos]);
pos += 2;
for (i = 0; i < ext_count; ++i)
- {
- /* write extension type */
- gnutls_write_uint16 (exten_t, &data[pos]);
- pos += 2;
- gnutls_write_uint16 (ext_length, &data[pos]);
- pos += 2;
- /* we might want to generate random data here */
- memset (&data[pos], 0, ext_length);
- pos += ext_length;
- }
+ {
+ /* write extension type */
+ gnutls_write_uint16 (exten_t, &data[pos]);
+ pos += 2;
+ gnutls_write_uint16 (ext_length, &data[pos]);
+ pos += 2;
+ /* we might want to generate random data here */
+ memset (&data[pos], 0, ext_length);
+ pos += ext_length;
+ }
if (connect (sd, &sa, sizeof (struct sockaddr_in)) < 0)
- {
- fprintf (stderr, "%s\n", MHD_E_FAILED_TO_CONNECT);
- ret = -1;
- goto cleanup;
- }
+ {
+ fprintf (stderr, "%s\n", MHD_E_FAILED_TO_CONNECT);
+ ret = -1;
+ goto cleanup;
+ }
gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) (long) sd);
- if (gen_test_file_url (url, DEAMON_TEST_PORT))
- {
- ret = -1;
- goto cleanup;
- }
+ if (gen_test_file_url (url,
+ sizeof (url),
+ port))
+ {
+ ret = -1;
+ goto cleanup;
+ }
/* this should crash the server */
ret = gnutls_send_handshake (session, data, datalen,
- GNUTLS_HANDSHAKE_CLIENT_HELLO);
+ GNUTLS_HANDSHAKE_CLIENT_HELLO);
/* advance to STATE2 */
session->internals.handshake_state = STATE2;
@@ -184,10 +190,10 @@
/* make sure daemon is still functioning */
if (CURLE_OK != send_curl_req (url, &cbc, "AES128-SHA",
MHD_GNUTLS_PROTOCOL_TLS1_2))
- {
- ret = -1;
- goto cleanup;
- }
+ {
+ ret = -1;
+ goto cleanup;
+ }
cleanup:
if (-1 != sd)
@@ -207,65 +213,80 @@
gnutls_datum_t key;
gnutls_datum_t cert;
gnutls_certificate_credentials_t xcred;
-
const int ext_arr[] = {
GNUTLS_EXTENSION_SERVER_NAME,
-1
};
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3080;
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
MHD_gtls_global_set_log_level (11);
if ((test_fd = setup_test_file ()) == NULL)
- {
- fprintf (stderr, MHD_E_TEST_FILE_CREAT);
- return -1;
- }
-
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return -1;
- }
-
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
- MHD_USE_ERROR_LOG, DEAMON_TEST_PORT,
+ {
+ fprintf (stderr, MHD_E_TEST_FILE_CREAT);
+ return -1;
+ }
+
+ if (! testsuite_curl_global_init ())
+ return 99;
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
+ | MHD_USE_ERROR_LOG, port,
NULL, NULL, &http_ahc, NULL,
MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
MHD_OPTION_END);
if (d == NULL)
+ {
+ fprintf (stderr, "%s\n", MHD_E_SERVER_INIT);
+ return -1;
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, "%s\n", MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (d); return -1;
}
+ port = (int) dinfo->port;
+ }
i = 0;
setup_session (&session, &key, &cert, &xcred);
- errorCount += test_hello_extension (session, ext_arr[i], 1, 16);
+ errorCount += test_hello_extension (session, port, ext_arr[i], 1, 16);
teardown_session (session, &key, &cert, xcred);
#if 1
i = 0;
while (ext_arr[i] != -1)
- {
- setup_session (&session, &key, &cert, &xcred);
- errorCount += test_hello_extension (session, ext_arr[i], 1, 16);
- teardown_session (session, &key, &cert, xcred);
-
- setup_session (&session, &key, &cert, &xcred);
- errorCount += test_hello_extension (session, ext_arr[i], 3, 8);
- teardown_session (session, &key, &cert, xcred);
-
- /* this test specifically tests the issue raised in CVE-2008-1948 */
- setup_session (&session, &key, &cert, &xcred);
- errorCount += test_hello_extension (session, ext_arr[i], 6, 0);
- teardown_session (session, &key, &cert, xcred);
- i++;
- }
+ {
+ setup_session (&session, &key, &cert, &xcred);
+ errorCount += test_hello_extension (session, port, ext_arr[i], 1, 16);
+ teardown_session (session, &key, &cert, xcred);
+
+ setup_session (&session, &key, &cert, &xcred);
+ errorCount += test_hello_extension (session, port, ext_arr[i], 3, 8);
+ teardown_session (session, &key, &cert, xcred);
+
+ /* this test specifically tests the issue raised in CVE-2008-1948 */
+ setup_session (&session, &key, &cert, &xcred);
+ errorCount += test_hello_extension (session, port, ext_arr[i], 6, 0);
+ teardown_session (session, &key, &cert, xcred);
+ i++;
+ }
#endif
print_test_result (errorCount, argv[0]);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/test_tls_options.c
^
|
@@ -28,7 +28,9 @@
#include "microhttpd.h"
#include <sys/stat.h>
#include <limits.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#include <gcrypt.h>
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#include "tls_test_common.h"
extern const char srv_key_pem[];
@@ -41,35 +43,40 @@
*
*/
static int
-test_unmatching_ssl_version (void * cls, const char *cipher_suite,
+test_unmatching_ssl_version (void *cls, int port, const char *cipher_suite,
int curl_req_ssl_version)
{
struct CBC cbc;
+ char url[255];
+ (void) cls; /* Unused. Silent compiler warning. */
if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
- {
- fprintf (stderr, "Error: failed to allocate: %s\n",
- strerror (errno));
- return -1;
- }
+ {
+ fprintf (stderr, "Error: failed to allocate: %s\n",
+ strerror (errno));
+ return -1;
+ }
cbc.size = 256;
cbc.pos = 0;
- char url[255];
- if (gen_test_file_url (url, DEAMON_TEST_PORT))
- {
- free (cbc.buf);
- fprintf (stderr, "Internal error in gen_test_file_url\n");
- return -1;
- }
+ if (gen_test_file_url (url,
+ sizeof (url),
+ port))
+ {
+ free (cbc.buf);
+ fprintf (stderr,
+ "Internal error in gen_test_file_url\n");
+ return -1;
+ }
/* assert daemon *rejected* request */
if (CURLE_OK ==
send_curl_req (url, &cbc, cipher_suite, curl_req_ssl_version))
- {
- free (cbc.buf);
- fprintf (stderr, "cURL failed to reject request despite SSL version missmatch!\n");
- return -1;
- }
+ {
+ free (cbc.buf);
+ fprintf (stderr,
+ "cURL failed to reject request despite SSL version mismatch!\n");
+ return -1;
+ }
free (cbc.buf);
return 0;
@@ -83,17 +90,29 @@
unsigned int errorCount = 0;
const char *ssl_version;
int daemon_flags =
- MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | MHD_USE_ERROR_LOG;
+ MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_TLS | MHD_USE_ERROR_LOG;
+ int port;
+ const char *aes128_sha = "AES128-SHA";
+ const char *aes256_sha = "AES256-SHA";
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 3010;
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
- if (curl_check_version (MHD_REQ_CURL_VERSION))
- {
- return 77;
- }
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (curl_check_version (MHD_REQ_CURL_VERSION))
+ {
+ return 77;
+ }
ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
if (NULL == ssl_version)
{
@@ -106,49 +125,46 @@
return 77;
}
- if (0 != curl_global_init (CURL_GLOBAL_ALL))
- {
- fprintf (stderr, "Error: %s\n", strerror (errno));
- return 99;
- }
+ if (! testsuite_curl_global_init ())
+ return 99;
- const char *aes128_sha = "AES128-SHA";
- const char *aes256_sha = "AES256-SHA";
- if (curl_uses_nss_ssl() == 0)
- {
- aes128_sha = "rsa_aes_128_sha";
- aes256_sha = "rsa_aes_256_sha";
- }
+ if (curl_uses_nss_ssl () == 0)
+ {
+ aes128_sha = "rsa_aes_128_sha";
+ aes256_sha = "rsa_aes_256_sha";
+ }
if (0 !=
- test_wrap ("TLS1.0-AES-SHA1",
- &test_https_transfer, NULL, daemon_flags,
- aes128_sha,
- CURL_SSLVERSION_TLSv1,
- MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
- MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
- MHD_OPTION_HTTPS_PRIORITIES, "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+RSA:+COMP-NULL",
- MHD_OPTION_END))
- {
- fprintf (stderr, "TLS1.0-AES-SHA1 test failed\n");
- errorCount++;
- }
+ test_wrap ("TLS1.0-AES-SHA1",
+ &test_https_transfer, NULL, port, daemon_flags,
+ aes128_sha,
+ CURL_SSLVERSION_TLSv1,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+ MHD_OPTION_HTTPS_PRIORITIES,
+ "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+RSA:+COMP-NULL",
+ MHD_OPTION_END))
+ {
+ fprintf (stderr, "TLS1.0-AES-SHA1 test failed\n");
+ errorCount++;
+ }
fprintf (stderr,
- "The following handshake should fail (and print an error message)...\n");
+ "The following handshake should fail (and print an error message)...\n");
if (0 !=
- test_wrap ("TLS1.0 vs SSL3",
- &test_unmatching_ssl_version, NULL, daemon_flags,
- aes256_sha,
- CURL_SSLVERSION_SSLv3,
- MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
- MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
- MHD_OPTION_HTTPS_PRIORITIES, "NONE:+VERS-TLS1.0:+AES-256-CBC:+SHA1:+RSA:+COMP-NULL",
- MHD_OPTION_END))
- {
- fprintf (stderr, "TLS1.0 vs SSL3 test failed\n");
- errorCount++;
- }
+ test_wrap ("TLS1.0 vs SSL3",
+ &test_unmatching_ssl_version, NULL, port, daemon_flags,
+ aes256_sha,
+ CURL_SSLVERSION_SSLv3,
+ MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+ MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+ MHD_OPTION_HTTPS_PRIORITIES,
+ "NONE:+VERS-TLS1.0:+AES-256-CBC:+SHA1:+RSA:+COMP-NULL",
+ MHD_OPTION_END))
+ {
+ fprintf (stderr, "TLS1.0 vs SSL3 test failed\n");
+ errorCount++;
+ }
curl_global_cleanup ();
return errorCount != 0 ? 1 : 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/tls_test_common.c
^
|
@@ -27,34 +27,32 @@
#include "tls_test_keys.h"
-int curl_check_version (const char *req_version, ...);
-
FILE *
setup_ca_cert ()
{
FILE *cert_fd;
if (NULL == (cert_fd = fopen (ca_cert_file_name, "wb+")))
- {
- fprintf (stderr, "Error: failed to open `%s': %s\n",
- ca_cert_file_name, strerror (errno));
- return NULL;
- }
+ {
+ fprintf (stderr, "Error: failed to open `%s': %s\n",
+ ca_cert_file_name, strerror (errno));
+ return NULL;
+ }
if (fwrite (ca_cert_pem, sizeof (char), strlen (ca_cert_pem) + 1, cert_fd)
!= strlen (ca_cert_pem) + 1)
- {
- fprintf (stderr, "Error: failed to write `%s. %s'\n",
- ca_cert_file_name, strerror (errno));
- fclose (cert_fd);
- return NULL;
- }
+ {
+ fprintf (stderr, "Error: failed to write `%s. %s'\n",
+ ca_cert_file_name, strerror (errno));
+ fclose (cert_fd);
+ return NULL;
+ }
if (fflush (cert_fd))
- {
- fprintf (stderr, "Error: failed to flush ca cert file stream. %s\n",
- strerror (errno));
- fclose (cert_fd);
- return NULL;
- }
+ {
+ fprintf (stderr, "Error: failed to flush ca cert file stream. %s\n",
+ strerror (errno));
+ fclose (cert_fd);
+ return NULL;
+ }
return cert_fd;
}
@@ -64,31 +62,35 @@
*/
int
test_daemon_get (void *cls,
- const char *cipher_suite, int proto_version,
- int port,
- int ver_peer)
+ const char *cipher_suite,
+ int proto_version,
+ int port,
+ int ver_peer)
{
CURL *c;
struct CBC cbc;
CURLcode errornum;
char url[255];
size_t len;
+ (void) cls; /* Unused. Silence compiler warning. */
len = strlen (test_data);
if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
- {
- fprintf (stderr, MHD_E_MEM);
- return -1;
- }
+ {
+ fprintf (stderr, MHD_E_MEM);
+ return -1;
+ }
cbc.size = len;
cbc.pos = 0;
/* construct url - this might use doc_path */
- gen_test_file_url (url, port);
+ gen_test_file_url (url,
+ sizeof (url),
+ port);
c = curl_easy_init ();
#if DEBUG_HTTPS_TEST
- curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
#endif
curl_easy_setopt (c, CURLOPT_URL, url);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
@@ -106,30 +108,30 @@
curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, ver_peer);
if (ver_peer)
curl_easy_setopt (c, CURLOPT_CAINFO, ca_cert_file_name);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
-
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr, "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- free (cbc.buf);
- return errornum;
- }
+ {
+ fprintf (stderr, "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ free (cbc.buf);
+ return errornum;
+ }
curl_easy_cleanup (c);
if (memcmp (cbc.buf, test_data, len) != 0)
- {
- fprintf (stderr, "Error: local file & received file differ.\n");
- free (cbc.buf);
- return -1;
- }
+ {
+ fprintf (stderr, "Error: local file & received file differ.\n");
+ free (cbc.buf);
+ return -1;
+ }
free (cbc.buf);
return 0;
@@ -137,18 +139,29 @@
void
-print_test_result (int test_outcome, char *test_name)
+print_test_result (int test_outcome,
+ char *test_name)
{
if (test_outcome != 0)
- fprintf (stderr, "running test: %s [fail: %u]\n", test_name, (unsigned int)test_outcome);
+ fprintf (stderr,
+ "running test: %s [fail: %u]\n",
+ test_name, (unsigned
+ int)
+ test_outcome);
#if 0
else
- fprintf (stdout, "running test: %s [pass]\n", test_name);
+ fprintf (stdout,
+ "running test: %s [pass]\n",
+ test_name);
#endif
}
+
size_t
-copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+copyBuffer (void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *ctx)
{
struct CBC *cbc = ctx;
@@ -159,45 +172,67 @@
return size * nmemb;
}
+
/**
* HTTP access handler call back
*/
-int
-http_ahc (void *cls, struct MHD_Connection *connection,
- const char *url, const char *method, const char *upload_data,
- const char *version, size_t *upload_data_size, void **ptr)
+enum MHD_Result
+http_ahc (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **ptr)
{
static int aptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (test_data),
- (void *) test_data,
- MHD_RESPMEM_PERSISTENT);
+ (void *) test_data,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
+
/* HTTP access handler call back */
-int
-http_dummy_ahc (void *cls, struct MHD_Connection *connection,
- const char *url, const char *method, const char *upload_data,
- const char *version, size_t *upload_data_size,
+enum MHD_Result
+http_dummy_ahc (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
void **ptr)
{
+ (void) cls;
+ (void) connection;
+ (void) url;
+ (void) method;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size;
+ (void) ptr; /* Unused. Silent compiler warning. */
return 0;
}
+
/**
* send a test http request to the daemon
* @param url
@@ -208,7 +243,9 @@
*/
/* TODO have test wrap consider a NULL cbc */
int
-send_curl_req (char *url, struct CBC * cbc, const char *cipher_suite,
+send_curl_req (char *url,
+ struct CBC *cbc,
+ const char *cipher_suite,
int proto_version)
{
CURL *c;
@@ -223,32 +260,32 @@
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
if (cbc != NULL)
- {
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_FILE, cbc);
- }
+ {
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_FILE, cbc);
+ }
/* TLS options */
curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
/* currently skip any peer authentication */
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr, "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- return errornum;
- }
+ {
+ fprintf (stderr, "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ return errornum;
+ }
curl_easy_cleanup (c);
return CURLE_OK;
@@ -258,138 +295,176 @@
/**
* compile test file url pointing to the current running directory path
*
- * @param url - char buffer into which the url is compiled
+ * @param[out] url - char buffer into which the url is compiled
+ * @param url_len number of bytes available in url
* @param port port to use for the test
* @return -1 on error
*/
int
-gen_test_file_url (char *url, int port)
+gen_test_file_url (char *url,
+ size_t url_len,
+ int port)
{
int ret = 0;
char *doc_path;
size_t doc_path_len;
/* setup test file path, url */
+#ifdef PATH_MAX
doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
+#else /* ! PATH_MAX */
+ doc_path_len = 4096;
+#endif /* ! PATH_MAX */
+#ifdef WINDOWS
+ size_t i;
+#endif /* ! WINDOWS */
if (NULL == (doc_path = malloc (doc_path_len)))
- {
- fprintf (stderr, MHD_E_MEM);
- return -1;
- }
- if (getcwd (doc_path, doc_path_len) == NULL)
- {
- fprintf (stderr, "Error: failed to get working directory. %s\n",
- strerror (errno));
- ret = -1;
- }
+ {
+ fprintf (stderr, MHD_E_MEM);
+ return -1;
+ }
+ if (NULL == getcwd (doc_path, doc_path_len))
+ {
+ fprintf (stderr,
+ "Error: failed to get working directory. %s\n",
+ strerror (errno));
+ free (doc_path);
+ return -1;
+ }
#ifdef WINDOWS
+ for (i = 0; i < doc_path_len; i++)
{
- int i;
- for (i = 0; i < doc_path_len; i++)
- {
- if (doc_path[i] == 0)
- break;
- if (doc_path[i] == '\\')
- {
- doc_path[i] = '/';
- }
- if (doc_path[i] != ':')
- continue;
- if (i == 0)
- break;
- doc_path[i] = doc_path[i - 1];
- doc_path[i - 1] = '/';
- }
+ if (doc_path[i] == 0)
+ break;
+ if (doc_path[i] == '\\')
+ {
+ doc_path[i] = '/';
+ }
+ if (doc_path[i] != ':')
+ continue;
+ if (i == 0)
+ break;
+ doc_path[i] = doc_path[i - 1];
+ doc_path[i - 1] = '/';
}
#endif
- /* construct url - this might use doc_path */
- if (sprintf (url, "%s:%d%s/%s", "https://127.0.0.1", port,
- doc_path, "urlpath") < 0)
+ /* construct url */
+ if (snprintf (url,
+ url_len,
+ "%s:%d%s/%s",
+ "https://127.0.0.1",
+ port,
+ doc_path,
+ "urlpath") >= (long long) url_len)
ret = -1;
free (doc_path);
return ret;
}
+
/**
* test HTTPS file transfer
*/
int
-test_https_transfer (void *cls, const char *cipher_suite, int proto_version)
+test_https_transfer (void *cls,
+ int port,
+ const char *cipher_suite,
+ int proto_version)
{
int len;
int ret = 0;
struct CBC cbc;
char url[255];
+ (void) cls; /* Unused. Silent compiler warning. */
len = strlen (test_data);
if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
- {
- fprintf (stderr, MHD_E_MEM);
- return -1;
- }
+ {
+ fprintf (stderr, MHD_E_MEM);
+ return -1;
+ }
cbc.size = len;
cbc.pos = 0;
- if (gen_test_file_url (url, DEAMON_TEST_PORT))
- {
- ret = -1;
- goto cleanup;
- }
+ if (gen_test_file_url (url,
+ sizeof (url),
+ port))
+ {
+ ret = -1;
+ goto cleanup;
+ }
- if (CURLE_OK != send_curl_req (url, &cbc, cipher_suite, proto_version))
- {
- ret = -1;
- goto cleanup;
- }
+ if (CURLE_OK !=
+ send_curl_req (url, &cbc, cipher_suite, proto_version))
+ {
+ ret = -1;
+ goto cleanup;
+ }
- /* compare test file & daemon responce */
+ /* compare test file & daemon response */
if ( (len != strlen (test_data)) ||
- (memcmp (cbc.buf,
- test_data,
- len) != 0) )
- {
- fprintf (stderr, "Error: local file & received file differ.\n");
- ret = -1;
- }
+ (memcmp (cbc.buf,
+ test_data,
+ len) != 0) )
+ {
+ fprintf (stderr, "Error: local file & received file differ.\n");
+ ret = -1;
+ }
cleanup:
free (cbc.buf);
return ret;
}
+
/**
* setup test case
*
* @param d
* @param daemon_flags
* @param arg_list
- * @return
+ * @return port number on success or zero on failure
*/
int
-setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
+setup_testcase (struct MHD_Daemon **d, int port, int daemon_flags, va_list
+ arg_list)
{
- *d = MHD_start_daemon_va (daemon_flags, DEAMON_TEST_PORT,
+ *d = MHD_start_daemon_va (daemon_flags, port,
NULL, NULL, &http_ahc, NULL, arg_list);
if (*d == NULL)
+ {
+ fprintf (stderr, MHD_E_SERVER_INIT);
+ return 0;
+ }
+
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (*d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, MHD_E_SERVER_INIT);
- return -1;
+ MHD_stop_daemon (*d);
+ return 0;
}
+ port = (int) dinfo->port;
+ }
- return 0;
+ return port;
}
+
void
teardown_testcase (struct MHD_Daemon *d)
{
MHD_stop_daemon (d);
}
+
int
-setup_session (gnutls_session_t * session,
- gnutls_datum_t * key,
- gnutls_datum_t * cert,
- gnutls_certificate_credentials_t * xcred)
+setup_session (gnutls_session_t *session,
+ gnutls_datum_t *key,
+ gnutls_datum_t *cert,
+ gnutls_certificate_credentials_t *xcred)
{
int ret;
const char *err_pos;
@@ -397,43 +472,44 @@
gnutls_certificate_allocate_credentials (xcred);
key->size = strlen (srv_key_pem) + 1;
key->data = malloc (key->size);
- if (NULL == key->data)
- {
- gnutls_certificate_free_credentials (*xcred);
- return -1;
- }
+ if (NULL == key->data)
+ {
+ gnutls_certificate_free_credentials (*xcred);
+ return -1;
+ }
memcpy (key->data, srv_key_pem, key->size);
cert->size = strlen (srv_self_signed_cert_pem) + 1;
cert->data = malloc (cert->size);
if (NULL == cert->data)
- {
- gnutls_certificate_free_credentials (*xcred);
- free (key->data);
- return -1;
- }
+ {
+ gnutls_certificate_free_credentials (*xcred);
+ free (key->data);
+ return -1;
+ }
memcpy (cert->data, srv_self_signed_cert_pem, cert->size);
gnutls_certificate_set_x509_key_mem (*xcred, cert, key,
- GNUTLS_X509_FMT_PEM);
+ GNUTLS_X509_FMT_PEM);
gnutls_init (session, GNUTLS_CLIENT);
ret = gnutls_priority_set_direct (*session,
- "NORMAL", &err_pos);
+ "NORMAL", &err_pos);
if (ret < 0)
- {
- gnutls_deinit (*session);
- gnutls_certificate_free_credentials (*xcred);
- free (key->data);
- return -1;
- }
- gnutls_credentials_set (*session,
- GNUTLS_CRD_CERTIFICATE,
- *xcred);
+ {
+ gnutls_deinit (*session);
+ gnutls_certificate_free_credentials (*xcred);
+ free (key->data);
+ return -1;
+ }
+ gnutls_credentials_set (*session,
+ GNUTLS_CRD_CERTIFICATE,
+ *xcred);
return 0;
}
+
int
teardown_session (gnutls_session_t session,
- gnutls_datum_t * key,
- gnutls_datum_t * cert,
+ gnutls_datum_t *key,
+ gnutls_datum_t *cert,
gnutls_certificate_credentials_t xcred)
{
free (key->data);
@@ -447,39 +523,66 @@
return 0;
}
+
/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) */
int
test_wrap (const char *test_name, int
- (*test_function) (void * cls, const char *cipher_suite,
- int proto_version), void * cls,
+ (*test_function)(void *cls, int port, const char *cipher_suite,
+ int proto_version), void *cls,
+ int port,
int daemon_flags, const char *cipher_suite, int proto_version, ...)
{
int ret;
va_list arg_list;
struct MHD_Daemon *d;
+ (void) cls; /* Unused. Silent compiler warning. */
va_start (arg_list, proto_version);
- if (setup_testcase (&d, daemon_flags, arg_list) != 0)
- {
- va_end (arg_list);
- fprintf (stderr, "Failed to setup testcase %s\n", test_name);
- return -1;
- }
+ port = setup_testcase (&d, port, daemon_flags, arg_list);
+ if (0 == port)
+ {
+ va_end (arg_list);
+ fprintf (stderr, "Failed to setup testcase %s\n", test_name);
+ return -1;
+ }
#if 0
fprintf (stdout, "running test: %s ", test_name);
#endif
- ret = test_function (NULL, cipher_suite, proto_version);
+ ret = test_function (NULL, port, cipher_suite, proto_version);
#if 0
if (ret == 0)
- {
- fprintf (stdout, "[pass]\n");
- }
+ {
+ fprintf (stdout, "[pass]\n");
+ }
else
- {
- fprintf (stdout, "[fail]\n");
- }
+ {
+ fprintf (stdout, "[fail]\n");
+ }
#endif
teardown_testcase (d);
va_end (arg_list);
return ret;
}
+
+
+int
+testsuite_curl_global_init (void)
+{
+ CURLcode res;
+#if LIBCURL_VERSION_NUM >= 0x073800
+ if (CURLSSLSET_OK != curl_global_sslset (CURLSSLBACKEND_GNUTLS, NULL, NULL))
+ {
+ if (CURLSSLSET_TOO_LATE == curl_global_sslset (CURLSSLBACKEND_OPENSSL, NULL,
+ NULL))
+ fprintf (stderr, "WARNING: libcurl was already initialised.\n");
+ }
+#endif /* LIBCURL_VERSION_NUM >= 0x07380 */
+ res = curl_global_init (CURL_GLOBAL_ALL);
+ if (CURLE_OK != res)
+ {
+ fprintf (stderr, "libcurl initialisation error: %s\n", curl_easy_strerror (
+ res));
+ return 0;
+ }
+ return 1;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/tls_test_common.h
^
|
@@ -32,25 +32,27 @@
#define DEBUG_HTTPS_TEST 0
#define CURL_VERBOS_LEVEL 0
-#define DEAMON_TEST_PORT 4233
-
#define test_data "Hello World\n"
#define ca_cert_file_name "tmp_ca_cert.pem"
-#define EMPTY_PAGE "<html><head><title>Empty page</title></head><body>Empty page</body></html>"
-#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
+#define EMPTY_PAGE \
+ "<html><head><title>Empty page</title></head><body>Empty page</body></html>"
+#define PAGE_NOT_FOUND \
+ "<html><head><title>File not found</title></head><body>File not found</body></html>"
#define MHD_E_MEM "Error: memory error\n"
#define MHD_E_SERVER_INIT "Error: failed to start server\n"
#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
-#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n"
+#define MHD_E_FAILED_TO_CONNECT \
+ "Error: server connection could not be established\n"
/* TODO rm if unused */
struct https_test_data
{
void *cls;
+ int port;
const char *cipher_suite;
int proto_version;
};
@@ -69,31 +71,36 @@
};
-int curl_check_version (const char *req_version, ...);
-int curl_uses_nss_ssl ();
+int
+curl_check_version (const char *req_version, ...);
+
+int
+curl_uses_nss_ssl (void);
FILE *
-setup_ca_cert ();
+setup_ca_cert (void);
/**
* perform cURL request for file
*/
int
-test_daemon_get (void * cls,
- const char *cipher_suite, int proto_version,
+test_daemon_get (void *cls,
+ const char *cipher_suite, int proto_version,
int port, int ver_peer);
-void print_test_result (int test_outcome, char *test_name);
+void
+print_test_result (int test_outcome, char *test_name);
-size_t copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx);
+size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx);
-int
+enum MHD_Result
http_ahc (void *cls, struct MHD_Connection *connection,
const char *url, const char *method, const char *upload_data,
const char *version, size_t *upload_data_size, void **ptr);
-int
+enum MHD_Result
http_dummy_ahc (void *cls, struct MHD_Connection *connection,
const char *url, const char *method, const char *upload_data,
const char *version, size_t *upload_data_size,
@@ -103,39 +110,51 @@
/**
* compile test file url pointing to the current running directory path
*
- * @param url - char buffer into which the url is compiled
+ * @param[out] url - char buffer into which the url is compiled
+ * @param url_len number of bytes available in @a url
* @param port port to use for the test
* @return -1 on error
*/
-int gen_test_file_url (char *url, int port);
+int
+gen_test_file_url (char *url,
+ size_t url_len,
+ int port);
int
send_curl_req (char *url, struct CBC *cbc, const char *cipher_suite,
int proto_version);
int
-test_https_transfer (void *cls, const char *cipher_suite, int proto_version);
+test_https_transfer (void *cls, int port, const char *cipher_suite, int
+ proto_version);
int
-setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list);
+setup_testcase (struct MHD_Daemon **d, int port, int daemon_flags, va_list
+ arg_list);
+
+void
+teardown_testcase (struct MHD_Daemon *d);
-void teardown_testcase (struct MHD_Daemon *d);
int
-setup_session (gnutls_session_t * session,
- gnutls_datum_t * key,
- gnutls_datum_t * cert,
- gnutls_certificate_credentials_t * xcred);
+setup_session (gnutls_session_t *session,
+ gnutls_datum_t *key,
+ gnutls_datum_t *cert,
+ gnutls_certificate_credentials_t *xcred);
int
teardown_session (gnutls_session_t session,
- gnutls_datum_t * key,
- gnutls_datum_t * cert,
+ gnutls_datum_t *key,
+ gnutls_datum_t *cert,
gnutls_certificate_credentials_t xcred);
int
test_wrap (const char *test_name, int
- (*test_function) (void * cls, const char *cipher_suite,
- int proto_version), void *test_function_cls,
+ (*test_function)(void *cls, int port, const char *cipher_suite,
+ int proto_version), void *cls,
+ int port,
int daemon_flags, const char *cipher_suite, int proto_version, ...);
+
+int testsuite_curl_global_init (void);
+
#endif /* TLS_TEST_COMMON_H_ */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/https/tls_test_keys.h
^
|
@@ -22,152 +22,157 @@
/* Test Certificates */
-/* Certificate Authority key */
-const char ca_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEowIBAAKCAQEA0EdlP613rjFvEj93tGo9fzBoKWU3CW+AbbfcJ397C89MyZ9J\n"
- "rlxyLGfa6qVX7CFVNmzgWWfcl2tHlw/fZmWtf/SFgrlkldvuGyY8H3n2HuMsWz/E\n"
- "h7n5VgwBX8NsP4eZNmikepxpr1mYx25K8FjnsKjAR9jGUSV8UfZ7VLIY0x/yqe+3\n"
- "32oqc4D/wJbV1AwwvC5Xf9rvHJwcZg57eqbDCL/4GDDk7d9Gark4XK6ZG+FnnxQn\n"
- "4a4jIdf4FoPp9s0EieHrHwYzs/uBqmfCSF4wXiaO8bmEwtbAsVbZH74Le7ggUbEe\n"
- "o+jan9XK0dE88AIImGzgoBnlic/Rr7J8OWA+iwIDAQABAoIBAEICZqXkUdpsw2F6\n"
- "qPMOergNPO3lrKg6ZO8hBs6j2fj3tcPuzljK5sqJDboxNejZ9Zo+rmnXf3Oj5fgL\n"
- "6UcYMYEsm4W/QRA3uEJ1fzeQnT7Ty9KNprlHaSzquCLEGlIWJSo3xu0vFlWjJUcL\n"
- "fwemfaOhD/OVUeEU6s5FOngwy6pZUsOajs3fNRtwBGuuXjniKZZlpSf2Wqu3xpHZ\n"
- "31OF1V0ycUCGPPFtpmUCtnZhS9L8QBTkNtfTIdXv6SfoBRFm0oXb0uL5HGft6yc7\n"
- "eYRXIscllQciqG3ymJ/y9o0E3A0YsBVauQyi7OEk+Kg8uoYOBkZCIY69hoN2Znlk\n"
- "OY5S5Z0CgYEA3j8pRAJzvc827KcX4vJf05HYD4aCyaI80fNmx1DgXfglTSGLQ361\n"
- "6i05YW8WtIvgkma3wF+jJOckBCW/7iq8wAX7Kz75WKGRyyTEb0wSfjx0G8grxX4d\n"
- "7sTIAAOnQj5WT6E/bkqxQZAYnVtIPxKtSlwts0H/bjPVYwSFchHK7t8CgYEA7+ks\n"
- "C0EMjF8CDeCfvbOUGiiqAvU3G20LEC3WlJM3AU+J9Jzp6AMkgaIA8J5oNdsbFBn4\n"
- "N12JPOO+7WRUk6Av8bsh4faE36ThnHohgAL8guRU7jIXvsFyO5yiY7/o/0lES0/V\n"
- "6xkh/Epj4MReuCGkiD9ifCVAo+dhHskeE9qbYdUCgYA4yBpa7eV0UUTPIcHQkew5\n"
- "ucFh9hPkQDcZzP4tXlR0rbmaAz/5dp4zvmoyopdCeZpezS+VTtn3y7Y/+QUYbILc\n"
- "7KpHWkeKhX0iUbp+VQlEh12C25mTU62CG3SdzFEnc5XJsoDqRNsUzSP80B2dP8BW\n"
- "h0aFzg7csRGLwtP1WOZoMQKBgQCrgsKd+Q8Dexh421DXyX3jhZalLrEKxlXWZy60\n"
- "YNo98aLqYRNHbpe2pR6O5nARsGYXZMlyq0flY9um0sc0Epyz79g1NoufZrxzpUw1\n"
- "u+zRlnKxJtaa5KjJvRzKuvPTLYnJXXXM8Na/Cl+E3F3qvQJm9QlvPyKLCmsAGz+J\n"
- "agsTUQKBgC0wqqJ6b1tbrAD8AVeeAn/IiP1rxYpc3x2s6ikFO2FMHXHC9wgrRPOc\n"
- "mkokV+DrUOv3I/7jG8wQA/FmBUPy562a1bObIKzg6CPXzrN68AmNnOIVU+H8fdxI\n"
- "iGyfT8WNpcRmtN11v34qXHwOWGQhpyyk2yNa8VIBSpkShq/EseZ1\n"
- "-----END RSA PRIVATE KEY-----\n";
-
/* Certificate Authority cert */
-const char ca_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
- "MIIC6DCCAdKgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
- "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
- "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
- "0EdlP613rjFvEj93tGo9fzBoKWU3CW+AbbfcJ397C89MyZ9JrlxyLGfa6qVX7CFV\n"
- "NmzgWWfcl2tHlw/fZmWtf/SFgrlkldvuGyY8H3n2HuMsWz/Eh7n5VgwBX8NsP4eZ\n"
- "Nmikepxpr1mYx25K8FjnsKjAR9jGUSV8UfZ7VLIY0x/yqe+332oqc4D/wJbV1Aww\n"
- "vC5Xf9rvHJwcZg57eqbDCL/4GDDk7d9Gark4XK6ZG+FnnxQn4a4jIdf4FoPp9s0E\n"
- "ieHrHwYzs/uBqmfCSF4wXiaO8bmEwtbAsVbZH74Le7ggUbEeo+jan9XK0dE88AII\n"
- "mGzgoBnlic/Rr7J8OWA+iwIDAQABo0MwQTAPBgNVHRMBAf8EBTADAQH/MA8GA1Ud\n"
- "DwEB/wQFAwMHBAAwHQYDVR0OBBYEFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsGCSqG\n"
- "SIb3DQEBBQOCAQEAebD5m+vZkVXa8y+QZ5GtsiR9gpH+LKtdWBjk1kmfSgvQI/xA\n"
- "aDCV/9BhdNGIBOTYGkln8urWd7g2Mj3TwKEAfNTUFpAsrBAlSSLTGYCSt72S2NsS\n"
- "L/qUxmj1W6X95UHXCo49mSZx3LlaY3mz1L87gq/kK0XpzA3g2uF25jt84RvshsXy\n"
- "clOc+eRrVETqFZqer96WB7kzFTv+qmROQKmW8X4a2A5r5Jl4vRwOz5/rEeB9Qs0K\n"
- "rmK8+5HgvWd80WB8BtfFtZfoY/hHVM8nLD3ELVJrOKiTeIACunQFyT5lV0QkdmSA\n"
- "CGInU7jzs8nu+s2avf6j+eVZUbVJ+dFMApTJgg==\n"
- "-----END CERTIFICATE-----\n";
+const char ca_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIGITCCBAmgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MThaGA8yMTIxMDMxNDE3\n\
+MzYxOFowgYExCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMSEwHwYJKoZIhvcN\n\
+AQkBFhJub2JvZHlAZXhhbXBsZS5vcmcxEDAOBgNVBAMMB3Rlc3QtQ0EwggIiMA0G\n\
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDdaWupA4qZjCBNkJoJOm5xnCaizl36\n\
+ZLUwp4xBL/YfXPWE3LkmAREiVI/YnAb8l6G7CJnz8dTsOJWkNXG6T1KVP5/2RvBI\n\
+IaaaufRIAl7hEnj1j9E2hQlV2fxF2ZNhz+nqi0LqKV4LJSpclkXADf2FA9HsVRP/\n\
+B7zYh+DP0fSU8V6bsu8XCeRGshroAPrc8rH8lFEEXpNLNIqQr8yKx6SmdB6hfja6\n\
+6SQ0++qBhl0aJtn4LHWZohgjBmkIaGFPYIJLgxQ/xyp2Grz2q7lGKJ+zBkBF8iOP\n\
+t3x+F1hSCBnr/DGYWmjEm5tYm+7pyuriPddXdCc8+qa2LxMZo3EXxLo5YISpPCyw\n\
+Z7V3YAOZTr3m1C24LiYvPehCq1CTIkhhmqtlVJXU7ISD48cx9y+5Pi34wtbTI/gN\n\
+x4voyTLAfyavKMmIpxxIRsWldiF2n06HdvCRVdihDQUad10ygTmWf1J/s2ZETAtH\n\
+QaSd7MD389t6nQFtTIXigsNKnnDPlrtxt7rOLvLQeR0K04Gzrf/scheOanRAfOXH\n\
+KNBFU7YkDFG8rqizlC65rx9qeXFYXQcHZTuqxK7tgZnSgJat3E70VbTSCsEEG7eR\n\
+bNX/fChUKAIIpWaiW6HDlKLl6m2y+BzM91umBsKOqTvntMVFBSF9pVYlXK854aIR\n\
+q8A2Xujd012seQIDAQABo4GfMIGcMAsGA1UdDwQEAwICpDASBgNVHRMBAf8ECDAG\n\
+AQH/AgEBMB0GA1UdDgQWBBRYdUPApWoxw4U13Rqsjf9AHdbpLDATBgNVHSUEDDAK\n\
+BggrBgEFBQcDATAkBglghkgBhvhCAQ0EFxYVVGVzdCBsaWJtaWNyb2h0dHBkIENB\n\
+MB8GA1UdIwQYMBaAFFh1Q8ClajHDhTXdGqyN/0Ad1uksMA0GCSqGSIb3DQEBCwUA\n\
+A4ICAQBvrrcTKVeI1EYnXo4BQD4oCvf9z1fYQmL21EbHwgjg1nmaPkvStgWAc5p1\n\
+kKwySrpEMKXfu68X76RccXZyWWIamEjz2OCWYZgjX6d6FpjhLphL8WxXDy5C9eay\n\
+ixN7+URz2XQoi22wqR+tCPDhrIzcMPyMkx/6gRgcYeDnaFrkdSeSsKsID4plfcIj\n\
+ISWJDvv+IAgrtsG1NVHnGwpAv0od3A8/4/fR6PPyewaU3aydvjZ7Au8O9DGDjlU9\n\
+9HdlOkkY6GVJ1pfGZib7cV7lhy0D2kj1g9xZh97YjpoUfppPl9r+6A8gDm0hXlAD\n\
+TlzNYlwTb681ZEoSd9PiLEY8HETssHlays2dYXdcNwAEp69iIHz8q1Q98Be9LScl\n\
+WEzgaOT9U7lpIw/MWbELoMsC+Ecs1cVWBIuiIq8aSG2kRr1x3S8yVXbAohAXif2s\n\
+E6puieM/VJ25iaNhkbLmDkk58QVVmn9NZNv6ETxuSQMp9e0EwbVlj68vzClQ91Y/\n\
+nmAiGcLFUEwB9G0szv9+vR+oDW4IkvdFZSUbcICd2cnynnwAD395onqS4hEZO1xM\n\
+Gy5ZldbTMTjgn7fChNopz15ChPBnwFIjhm+S0CyiLRQAowfknRVq2IBkj7/5kOWg\n\
+4mcxcq76HoQWK/8X/8RFL1eFVAvY7TNHYJ0RS51DMuwCNQictA==\n\
+-----END CERTIFICATE-----";
-/* test server CA signed certificates */
-const char srv_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
- "MIIDGzCCAgWgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
- "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
- "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
- "vfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW+K03KwEku55QvnUn\n"
- "dwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8ILq4sw32vo0fbMu5BZ\n"
- "F49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ020Q5EAAEseD1YtWC\n"
- "IpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6QYGGh1QmHRPAy3CB\n"
- "II6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6xyoOl204xuekZOaG9\n"
- "RUPId74Rtmwfi1TLbBzo2wIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
- "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFOFi4ilKOP1d\n"
- "XHlWCMwmVKr7mgy8MB8GA1UdIwQYMBaAFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsG\n"
- "CSqGSIb3DQEBBQOCAQEAHVWPxazupbOkG7Did+dY9z2z6RjTzYvurTtEKQgzM2Vz\n"
- "GQBA+3pZ3c5mS97fPIs9hZXfnQeelMeZ2XP1a+9vp35bJjZBBhVH+pqxjCgiUflg\n"
- "A3Zqy0XwwVCgQLE2HyaU3DLUD/aeIFK5gJaOSdNTXZLv43K8kl4cqDbMeRpVTbkt\n"
- "YmG4AyEOYRNKGTqMEJXJoxD5E3rBUNrVI/XyTjYrulxbNPcMWEHKNeeqWpKDYTFo\n"
- "Bb01PCthGXiq/4A2RLAFosadzRa8SBpoSjPPfZ0b2w4MJpReHqKbR5+T2t6hzml6\n"
- "4ToyOKPDmamiTuN5KzLN3cw7DQlvWMvqSOChPLnA3Q==\n"
- "-----END CERTIFICATE-----\n";
/* test server key */
-const char srv_signed_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEowIBAAKCAQEAvfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW\n"
- "+K03KwEku55QvnUndwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8IL\n"
- "q4sw32vo0fbMu5BZF49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ0\n"
- "20Q5EAAEseD1YtWCIpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6\n"
- "QYGGh1QmHRPAy3CBII6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6x\n"
- "yoOl204xuekZOaG9RUPId74Rtmwfi1TLbBzo2wIDAQABAoIBADu09WSICNq5cMe4\n"
- "+NKCLlgAT1NiQpLls1gKRbDhKiHU9j8QWNvWWkJWrCya4QdUfLCfeddCMeiQmv3K\n"
- "lJMvDs+5OjJSHFoOsGiuW2Ias7IjnIojaJalfBml6frhJ84G27IXmdz6gzOiTIer\n"
- "DjeAgcwBaKH5WwIay2TxIaScl7AwHBauQkrLcyb4hTmZuQh6ArVIN6+pzoVuORXM\n"
- "bpeNWl2l/HSN3VtUN6aCAKbN/X3o0GavCCMn5Fa85uJFsab4ss/uP+2PusU71+zP\n"
- "sBm6p/2IbGvF5k3VPDA7X5YX61sukRjRBihY8xSnNYx1UcoOsX6AiPnbhifD8+xQ\n"
- "Tlf8oJUCgYEA0BTfzqNpr9Wxw5/QXaSdw7S/0eP5a0C/nwURvmfSzuTD4equzbEN\n"
- "d+dI/s2JMxrdj/I4uoAfUXRGaabevQIjFzC9uyE3LaOyR2zhuvAzX+vVcs6bSXeU\n"
- "pKpCAcN+3Z3evMaX2f+z/nfSUAl2i4J2R+/LQAWJW4KwRky/m+cxpfUCgYEA6bN1\n"
- "b73bMgM8wpNt6+fcmS+5n0iZihygQ2U2DEud8nZJL4Nrm1dwTnfZfJBnkGj6+0Q0\n"
- "cOwj2KS0/wcEdJBP0jucU4v60VMhp75AQeHqidIde0bTViSRo3HWKXHBIFGYoU3T\n"
- "LyPyKndbqsOObnsFXHn56Nwhr2HLf6nw4taGQY8CgYBoSW36FLCNbd6QGvLFXBGt\n"
- "2lMhEM8az/K58kJ4WXSwOLtr6MD/WjNT2tkcy0puEJLm6BFCd6A6pLn9jaKou/92\n"
- "SfltZjJPb3GUlp9zn5tAAeSSi7YMViBrfuFiHObij5LorefBXISLjuYbMwL03MgH\n"
- "Ocl2JtA2ywMp2KFXs8GQWQKBgFyIVv5ogQrbZ0pvj31xr9HjqK6d01VxIi+tOmpB\n"
- "4ocnOLEcaxX12BzprW55ytfOCVpF1jHD/imAhb3YrHXu0fwe6DXYXfZV4SSG2vB7\n"
- "IB9z14KBN5qLHjNGFpMQXHSMek+b/ftTU0ZnPh9uEM5D3YqRLVd7GcdUhHvG8P8Q\n"
- "C9aXAoGBAJtID6h8wOGMP0XYX5YYnhlC7dOLfk8UYrzlp3xhqVkzKthTQTj6wx9R\n"
- "GtC4k7U1ki8oJsfcIlBNXd768fqDVWjYju5rzShMpo8OCTS6ipAblKjCxPPVhIpv\n"
- "tWPlbSn1qj6wylstJ5/3Z+ZW5H4wIKp5jmLiioDhcP0L/Ex3Zx8O\n"
- "-----END RSA PRIVATE KEY-----\n";
+const char srv_signed_key_pem[] =
+ "-----BEGIN PRIVATE KEY-----\n\
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrm8uH8V0P2Xbl\n\
+HCMq6PTIphDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZ\n\
+Vyg4ksOA7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd\n\
+6mi978n//bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5yg\n\
+CR99TDDHZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/Lni\n\
+CGO9uXGOgZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF\n\
+1N8GZZC7AgMBAAECggEAc0F/wR3qUurLX7U2KWuse9aNHFb84mBfCAw3hj7ddFEl\n\
+wto7EB50MA0KY4OI8u6fQH4E8zINoAciDzLqYJSxmbZhC1N5YX/Yc3qtZdB2b5tj\n\
+anbsSQqVo8YVPVDU4bCsG9vhArdd4JdCnD0DfA3ArZ3JAPwHsB4Ks1icLSOIGz0/\n\
+JvOZEryJBdwM6SKbzLMqVOGmYDiY6s7UpJ0rg3cOPqhdg5xv8XZATqXISU0mLBcq\n\
+RiS7lHZERASYON2rpznhBiCtikOcr/duQhvZ1uDSGfDzDJil+1hdS3RouS9WZCIe\n\
+p3CtvZhPLmv6kFg9YE+AovDwOOwNr0no3H9oJA2FgQKBgQDSWrE/MRMRpFJFBxxC\n\
+YckC2v8Y+7sVSMbFNq/0j2eRTql+8AeZBbAoGU4QHUcylCBkv33zDYRY52xNo32E\n\
+8mmH2O/pIcYy0LafrVZHdulf+fxybncObidxmmjR9C8aLzwRuIMtABz4simaQcBD\n\
+RhZJ1YCqVkfMr/PlbLzvC8V+FwKBgQDQ2MF/Yz/p7QEDHpfKdtx7+yK6i8IM+V8l\n\
+d2OuscNkQQywCVqE2vyRZJbjU9y+Om7alNKFPhhBzavdOxNWXGXmlBIlvo3v6M++\n\
+fTixza77LxHvbghH0ykplSwGh30vpHtvoxsRS5nRFxmsVK9jNYYT/Aes+J6MXlq7\n\
+PYAiZVQs/QKBgFKYY8JhPZCOyfLqsNDr3matoL6pkTLxSYMETyCi8lKe5XS/QOx3\n\
+zExia0FujZcxjGqiugymgRH7hI4TpOR/3qoFp2YN6enoA908zYTwDwCtgs9Xyo2y\n\
++O/lZkUSMTCB3X9DyNXxlm6cXjOAn8KKkZPaLlQz3qtjZ0vtX14pbBlvAoGBAKw0\n\
+vsCifvYNZhNDa5gXkFBu0MEPMm/uQ+Up37kRfPKyrJqO6+O2iiH81moWIWN93SBB\n\
+LKGPhQLlazxdVOGWCLQrDhevW2wiBQKmUFRULF+T/W72xL8sv7k49ndfyvq43ss7\n\
+q7sEIo4FRTcTERd179uUqmOXEWze9GOGH5y8/r6lAoGAG2YyqRWF+yxKlgR71b1Q\n\
+Zxv53WgXOUwemGRbXxE4g3gHpW5k9zWh4QTkbd0lDD+SQ0DBwZl/x/FWj43jUS+i\n\
+a5UojDUx8nYgjiAO7kppMlX3ZaJD1DkwEz+4HW9oPmOFt8smvuTVt0mm6tpmQdRA\n\
+yLwgQzGDGVJB6ETVJS7cwWs=\n\
+-----END PRIVATE KEY-----";
+
+/* test server CA signed certificates */
+const char srv_signed_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n\
+MIIFaTCCA1GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCUlUx\n\
+DzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MRswGQYDVQQKDBJ0ZXN0\n\
+LWxpYm1pY3JvaHR0cGQxITAfBgkqhkiG9w0BCQEWEm5vYm9keUBleGFtcGxlLm9y\n\
+ZzEQMA4GA1UEAwwHdGVzdC1DQTAgFw0yMTA0MDcxNzM2MjFaGA8yMTIxMDMxMzE3\n\
+MzYyMVowgYcxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNVBAcM\n\
+Bk1vc2NvdzEbMBkGA1UECgwSdGVzdC1saWJtaWNyb2h0dHBkMRQwEgYDVQQDDAt0\n\
+ZXN0LXNlcnZlcjEjMCEGA1UdEQwaRE5TOmxvY2FsaG9zdCxJUDoxMjcuMC4wLjEw\n\
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrm8uH8V0P2XblHCMq6PTI\n\
+phDcMmXEDiciCAAbfS7rVUyEJBgRpKSb+IXpj6jX1+e0+uncBxO9fesZVyg4ksOA\n\
+7jITGlzOjBvX6RzxkE9I96R3RCgzUHyYB8ayVSj1s/WmhorVPhKQjCmd6mi978n/\n\
+/bZKqTpq3OMpDrNC6AWTiHHP5KV9pp3Hsz1iAGK74sSVP3vhYD8IZ5ygCR99TDDH\n\
+ZfIvOmbqS60kx/UclUf2R4mSv/ZZHaHW7PeUhtUxzwOYqWVj0zLv/LniCGO9uXGO\n\
+gZHFfL8PhQwt6pNT5DaVmqx/uGwpsLiER4P74ngwroSjMwavYNlykuLF1N8GZZC7\n\
+AgMBAAGjgeEwgd4wCwYDVR0PBAQDAgWgMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/\n\
+BAwwCgYIKwYBBQUHAwEwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAA\n\
+AAAAAAAAAAAAAAABMB0GA1UdDgQWBBRifkHd2xWI51NhnH8sL66K8EedpjAoBglg\n\
+hkgBhvhCAQ0EGxYZVGVzdCBsaWJtaWNyb2h0dHBkIHNlcnZlcjARBglghkgBhvhC\n\
+AQEEBAMCBkAwHwYDVR0jBBgwFoAUWHVDwKVqMcOFNd0arI3/QB3W6SwwDQYJKoZI\n\
+hvcNAQELBQADggIBAJoIyNrnwQ+7WcJDaBjjuwSH0ORuK+E3zRI3+nDde08gyfeG\n\
+K4QozT2L574WzadTVLSiin9lRShYlp0nr60pmUb9+SKE0O7Cx+rYV0Rfu0KLYsYh\n\
+sAkb9J9t1fdIt54fXNcUtvfGPyM2lEI0KxMCGNV2wXDnwzdSNIU6Nk457MntfZdi\n\
+r1ISnS6fLd0BIKIGxfCFb10CexhNOSaExgpp1bxZovdYaQWggL0u8eC8j00sJ1C5\n\
+Qo4gQ1TQsead6zMs6m19TPLlV7hS+hfXj7yeJ/TTUj69bCjTIMp6HCFnfQbD84BI\n\
+HZDKk4Tob9vBRCKbY58kNXHyQ4nxvSCBlKI03VJjvzpsKTI/vW9JBivtnYtMbMl9\n\
+ouZal/IVsNqRCeiMTLky62qrFhZr2DHgPG5VcOGQ4y0X4vOgM9n/MMOGWcNBByLX\n\
+b5ZaYr7DPCcz9dYZgEbwXj8wnuAzM1sJ2igwTmO/vQsn1G2Q/h/JB471CD1avuuI\n\
+awKRqhU2KhYVrwo7ahJkPV9Lm6eoavq2Tu+e1o4qAFhPLMy/6F+bZmK6GfHMvP+L\n\
+v+GOQdUJ/vMMus/HB5N3cUZsu9rGnCCVgPW7pkHrp5bRtuVzBT78ISsxkGnOhfT7\n\
+6Kp7ApvfEX6/Y/vbDFBC4kyAvEIZ+F8AUkbvZ0+k8j5xlarNd6TQ3slEGi6O\n\
+-----END CERTIFICATE-----";
/* test server self signed certificates */
const char srv_self_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
- "MIIC+jCCAeSgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
- "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
- "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
- "tDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5kPqO1I7Cggzw68Y5\n"
- "jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qjMpnoGQ/2xmsNG/is\n"
- "i+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtdkrWxPKwYTgnDEN6D\n"
- "JL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFvKRuiU35tU7h7CPbL\n"
- "4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh1IhbklSh/Z6FA/e8\n"
- "hj0yVo2tdllXuJGVs3PIEwIDAQABo1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
- "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFDfU7pAv9LYn\n"
- "n7jb4WHl4+Vgi2FnMAsGCSqGSIb3DQEBBQOCAQEAkaembPQMmv6OOjbIod8zTatr\n"
- "x5Bwkwp3TOE1NRyy2OytzFIYRUkNrZYlcmrxcbNNycIK41CNVXbriFCF8gcmIq9y\n"
- "vaKZn8Gcy+vGggv+1BP9IAPBGKRwSi0wmq9JoGE8hx+qqTpRSdfbM/cps/09hicO\n"
- "0EIR7kWEbvnpMBcMKYOtYE9Gce7rdSMWVAsKc174xn8vW6TxCUvmWFv5DPg5HG1v\n"
- "y1SUX73qafRo+W6FN4UC/DHfwRhF8RSKEnVbmgDVCs6GHdKBjU2qRgYyj6nWZqK1\n"
- "XFUTWgia+Fl3D9vlsXaFcSZKA0Bq1eojl0B0AfeYAxTFwPWXscKvt/bXZfH8bg==\n"
- "-----END CERTIFICATE-----\n";
+ "MIIC+jCCAeSgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
+ "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
+ "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
+ "tDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5kPqO1I7Cggzw68Y5\n"
+ "jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qjMpnoGQ/2xmsNG/is\n"
+ "i+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtdkrWxPKwYTgnDEN6D\n"
+ "JL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFvKRuiU35tU7h7CPbL\n"
+ "4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh1IhbklSh/Z6FA/e8\n"
+ "hj0yVo2tdllXuJGVs3PIEwIDAQABo1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
+ "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFDfU7pAv9LYn\n"
+ "n7jb4WHl4+Vgi2FnMAsGCSqGSIb3DQEBBQOCAQEAkaembPQMmv6OOjbIod8zTatr\n"
+ "x5Bwkwp3TOE1NRyy2OytzFIYRUkNrZYlcmrxcbNNycIK41CNVXbriFCF8gcmIq9y\n"
+ "vaKZn8Gcy+vGggv+1BP9IAPBGKRwSi0wmq9JoGE8hx+qqTpRSdfbM/cps/09hicO\n"
+ "0EIR7kWEbvnpMBcMKYOtYE9Gce7rdSMWVAsKc174xn8vW6TxCUvmWFv5DPg5HG1v\n"
+ "y1SUX73qafRo+W6FN4UC/DHfwRhF8RSKEnVbmgDVCs6GHdKBjU2qRgYyj6nWZqK1\n"
+ "XFUTWgia+Fl3D9vlsXaFcSZKA0Bq1eojl0B0AfeYAxTFwPWXscKvt/bXZfH8bg==\n"
+ "-----END CERTIFICATE-----\n";
/* test server key */
const char srv_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
- "MIIEpAIBAAKCAQEAtDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5\n"
- "kPqO1I7Cggzw68Y5jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qj\n"
- "MpnoGQ/2xmsNG/isi+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtd\n"
- "krWxPKwYTgnDEN6DJL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFv\n"
- "KRuiU35tU7h7CPbL4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh\n"
- "1IhbklSh/Z6FA/e8hj0yVo2tdllXuJGVs3PIEwIDAQABAoIBAAEtcg+LFLGtoxjq\n"
- "b+tFttBJfbRcfdG6ocYqBGmUXF+MgFs573DHX3sHNOQxlaNHtSgIclF1eYgNZFFt\n"
- "VLIoBFTzfEQXoFosPUDoEuqVMeXLttmD7P2jwL780XJLZ4Xj6GY07npq1iGBcEZf\n"
- "yCcdoyGkr9jgc5Auyis8DStGg/jfUBC4NBvF0GnuuNPAdYRPKUpKw9EatI+FdMjy\n"
- "BuroD90fhdkK8EwMEVb9P17bdIc1MCIZFpUE9YHjVdK/oxCUhQ8KRfdbI4JU5Zh3\n"
- "UtO6Jm2wFuP3VmeVpPvE/C2rxI70pyl6HMSiFGNc0rhJYCQ+yhohWj7nZ67H4vLx\n"
- "plv5LxkCgYEAz7ewou8oFafDAMNoxaqKudvUg+lxXewdLDKaYBF5ACi9uAPCJ+v7\n"
- "M5c/fvPFn/XHzo7xaXbtTAH3Z5xzBs+80OsvL+e1Ut4xR+ELRkybknh/s2wQeABk\n"
- "Kb0vA59ukQGj12LV5phZMaVoXe6KJ7hZnN62d3K6m1wGE/k58i4pPLUCgYEA3hN8\n"
- "G95zW7g0jVdSr+KUeVmephph9yh8Yb+3I3ojwOIv6d45TopGx8pFZlnBAMZf1ZQx\n"
- "DIhzJNnaqZy/4w7RNaOGWnPA/5f+MIoHBiLGEEmfHC3lt087Yp9OuwDUHwpETYdV\n"
- "o+KBCvVh60Et3bZUgF/1k/3YXxn8J5dsmJsjNqcCgYBLflyRa1BrRnTGMz9CEDCp\n"
- "Si9b3h1Y4Hbd2GppHhCXMTd6yMrpDYhYANGQB3M9Juv+s88j4JhwNoq/uonH4Pqk\n"
- "B8Y3qAQr4RuSH0WkwDUOsALhqBX4N1QwI1USAQEDbNAqeP5698X7GD3tXcQSmZrg\n"
- "O8WfdjBCRNjkq4EW9xX/vQKBgQDONtmwJ0iHiu2BseyeVo/4fzfKlgUSNQ4K1rOA\n"
- "xhIdMeu8Bxa/z7caHsGC4SVPSuYCtbE2Kh6BwapChcPJXCD45fgEViiJLuJiwEj1\n"
- "caTpyvNsf1IoffJvCe9ZxtMyX549P8ZOgC3Dt0hN5CBrGLwu2Ox5l+YrqT10pi+5\n"
- "JZX1UQKBgQCrcXrdkkDAc/a4+PxNRpJRLcU4fhv8/lr+UWItE8eUe7bd25bTQfQm\n"
- "VpNKc/kAJ66PjIED6fy3ADhd2y4naT2a24uAgQ/M494J68qLnGh6K4JU/09uxR2v\n"
- "1i2q/4FNLdFFk1XP4iNnTHRLZ+NYr2p5Y9RcvQfTjOauz8Ahav0lyg==\n"
- "-----END RSA PRIVATE KEY-----\n";
+ "MIIEpAIBAAKCAQEAtDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5\n"
+ "kPqO1I7Cggzw68Y5jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qj\n"
+ "MpnoGQ/2xmsNG/isi+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtd\n"
+ "krWxPKwYTgnDEN6DJL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFv\n"
+ "KRuiU35tU7h7CPbL4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh\n"
+ "1IhbklSh/Z6FA/e8hj0yVo2tdllXuJGVs3PIEwIDAQABAoIBAAEtcg+LFLGtoxjq\n"
+ "b+tFttBJfbRcfdG6ocYqBGmUXF+MgFs573DHX3sHNOQxlaNHtSgIclF1eYgNZFFt\n"
+ "VLIoBFTzfEQXoFosPUDoEuqVMeXLttmD7P2jwL780XJLZ4Xj6GY07npq1iGBcEZf\n"
+ "yCcdoyGkr9jgc5Auyis8DStGg/jfUBC4NBvF0GnuuNPAdYRPKUpKw9EatI+FdMjy\n"
+ "BuroD90fhdkK8EwMEVb9P17bdIc1MCIZFpUE9YHjVdK/oxCUhQ8KRfdbI4JU5Zh3\n"
+ "UtO6Jm2wFuP3VmeVpPvE/C2rxI70pyl6HMSiFGNc0rhJYCQ+yhohWj7nZ67H4vLx\n"
+ "plv5LxkCgYEAz7ewou8oFafDAMNoxaqKudvUg+lxXewdLDKaYBF5ACi9uAPCJ+v7\n"
+ "M5c/fvPFn/XHzo7xaXbtTAH3Z5xzBs+80OsvL+e1Ut4xR+ELRkybknh/s2wQeABk\n"
+ "Kb0vA59ukQGj12LV5phZMaVoXe6KJ7hZnN62d3K6m1wGE/k58i4pPLUCgYEA3hN8\n"
+ "G95zW7g0jVdSr+KUeVmephph9yh8Yb+3I3ojwOIv6d45TopGx8pFZlnBAMZf1ZQx\n"
+ "DIhzJNnaqZy/4w7RNaOGWnPA/5f+MIoHBiLGEEmfHC3lt087Yp9OuwDUHwpETYdV\n"
+ "o+KBCvVh60Et3bZUgF/1k/3YXxn8J5dsmJsjNqcCgYBLflyRa1BrRnTGMz9CEDCp\n"
+ "Si9b3h1Y4Hbd2GppHhCXMTd6yMrpDYhYANGQB3M9Juv+s88j4JhwNoq/uonH4Pqk\n"
+ "B8Y3qAQr4RuSH0WkwDUOsALhqBX4N1QwI1USAQEDbNAqeP5698X7GD3tXcQSmZrg\n"
+ "O8WfdjBCRNjkq4EW9xX/vQKBgQDONtmwJ0iHiu2BseyeVo/4fzfKlgUSNQ4K1rOA\n"
+ "xhIdMeu8Bxa/z7caHsGC4SVPSuYCtbE2Kh6BwapChcPJXCD45fgEViiJLuJiwEj1\n"
+ "caTpyvNsf1IoffJvCe9ZxtMyX549P8ZOgC3Dt0hN5CBrGLwu2Ox5l+YrqT10pi+5\n"
+ "JZX1UQKBgQCrcXrdkkDAc/a4+PxNRpJRLcU4fhv8/lr+UWItE8eUe7bd25bTQfQm\n"
+ "VpNKc/kAJ66PjIED6fy3ADhd2y4naT2a24uAgQ/M494J68qLnGh6K4JU/09uxR2v\n"
+ "1i2q/4FNLdFFk1XP4iNnTHRLZ+NYr2p5Y9RcvQfTjOauz8Ahav0lyg==\n"
+ "-----END RSA PRIVATE KEY-----\n";
#endif
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/mhd_has_in_name.h
^
|
@@ -0,0 +1,65 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2016-2019 Karlson2k (Evgeny Grin)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/**
+ * @file testcurl/mhd_has_in_name.h
+ * @brief Static functions and macros helpers for testsuite.
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include <string.h>
+
+/**
+ * Check whether program name contains specific @a marker string.
+ * Only last component in pathname is checked for marker presence,
+ * all leading directories names (if any) are ignored. Directories
+ * separators are handled correctly on both non-W32 and W32
+ * platforms.
+ * @param prog_name program name, may include path
+ * @param marker marker to look for.
+ * @return zero if any parameter is NULL or empty string or
+ * @prog_name ends with slash or @marker is not found in
+ * program name, non-zero if @maker is found in program
+ * name.
+ */
+static int
+has_in_name (const char *prog_name, const char *marker)
+{
+ size_t name_pos;
+ size_t pos;
+
+ if (! prog_name || ! marker || ! prog_name[0] || ! marker[0])
+ return 0;
+
+ pos = 0;
+ name_pos = 0;
+ while (prog_name[pos])
+ {
+ if ('/' == prog_name[pos])
+ name_pos = pos + 1;
+#if defined(_WIN32) || defined(__CYGWIN__)
+ else if ('\\' == prog_name[pos])
+ name_pos = pos + 1;
+#endif /* _WIN32 || __CYGWIN__ */
+ pos++;
+ }
+ if (name_pos == pos)
+ return 0;
+ return strstr (prog_name + name_pos, marker) != (char*) 0;
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/perf_get.c
^
|
@@ -44,24 +44,33 @@
#include <string.h>
#include <time.h>
#include "gauger.h"
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
#include <sys/socket.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
/**
* How many rounds of operations do we do for each
* test?
*/
+#if MHD_CPU_COUNT > 8
+#ifndef _WIN32
+#define ROUNDS (1 + (30000 / 12) / MHD_CPU_COUNT)
+#else /* _WIN32 */
+#define ROUNDS (1 + (3000 / 12) / MHD_CPU_COUNT)
+#endif /* _WIN32 */
+#else
#define ROUNDS 500
+#endif
/**
* Do we use HTTP 1.1?
@@ -90,8 +99,8 @@
struct timeval tv;
gettimeofday (&tv, NULL);
- return (((unsigned long long) tv.tv_sec * 1000LL) +
- ((unsigned long long) tv.tv_usec / 1000LL));
+ return (((unsigned long long) tv.tv_sec * 1000LL)
+ + ((unsigned long long) tv.tv_usec / 1000LL));
}
@@ -99,7 +108,7 @@
* Start the timer.
*/
static void
-start_timer()
+start_timer ()
{
start_time = now ();
}
@@ -113,17 +122,17 @@
static void
stop (const char *desc)
{
- double rps = ((double) (ROUNDS * 1000)) / ((double) (now() - start_time));
+ double rps = ((double) (ROUNDS * 1000)) / ((double) (now () - start_time));
fprintf (stderr,
- "Sequential GETs using %s: %f %s\n",
- desc,
- rps,
- "requests/s");
+ "Sequential GETs using %s: %f %s\n",
+ desc,
+ rps,
+ "requests/s");
GAUGER (desc,
- "Sequential GETs",
- rps,
- "requests/s");
+ "Sequential GETs",
+ rps,
+ "requests/s");
}
@@ -137,8 +146,8 @@
static size_t
copyBuffer (void *ptr,
- size_t size, size_t nmemb,
- void *ctx)
+ size_t size, size_t nmemb,
+ void *ctx)
{
struct CBC *cbc = ctx;
@@ -149,7 +158,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -160,15 +170,17 @@
{
static int ptr;
const char *me = cls;
- int ret;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
if (ret == MHD_NO)
@@ -188,47 +200,64 @@
unsigned int i;
char url[64];
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
cbc.buf = buf;
cbc.size = 2048;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
start_timer ();
- for (i=0;i<ROUNDS;i++)
+ for (i = 0; i<ROUNDS; i++)
+ {
+ cbc.pos = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- cbc.pos = 0;
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
}
+ curl_easy_cleanup (c);
+ }
stop (poll_flag == MHD_USE_AUTO ? "internal thread with 'auto'" :
poll_flag == MHD_USE_POLL ? "internal thread with poll()" :
- poll_flag == MHD_USE_EPOLL ? "internal thread with epoll" : "internal thread with select()");
+ poll_flag == MHD_USE_EPOLL ? "internal thread with epoll" :
+ "internal thread with select()");
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 4;
@@ -249,48 +278,68 @@
unsigned int i;
char url[64];
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
cbc.buf = buf;
cbc.size = 2048;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
start_timer ();
- for (i=0;i<ROUNDS;i++)
+ for (i = 0; i<ROUNDS; i++)
+ {
+ cbc.pos = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- cbc.pos = 0;
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
}
- stop ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto' and thread per connection" :
- (poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
- (poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll and thread per connection" :
- "internal thread with select() and thread per connection");
+ curl_easy_cleanup (c);
+ }
+ stop ((poll_flag & MHD_USE_AUTO) ?
+ "internal thread with 'auto' and thread per connection" :
+ (poll_flag & MHD_USE_POLL) ?
+ "internal thread with poll() and thread per connection" :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "internal thread with epoll and thread per connection" :
+ "internal thread with select() and thread per connection");
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 64;
@@ -299,6 +348,7 @@
return 0;
}
+
static int
testMultithreadedPoolGet (int port, int poll_flag)
{
@@ -310,48 +360,66 @@
unsigned int i;
char url[64];
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
cbc.buf = buf;
cbc.size = 2048;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
start_timer ();
- for (i=0;i<ROUNDS;i++)
+ for (i = 0; i<ROUNDS; i++)
+ {
+ cbc.pos = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- cbc.pos = 0;
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
}
+ curl_easy_cleanup (c);
+ }
stop (0 != (poll_flag & MHD_USE_AUTO) ? "internal thread pool with 'auto'" :
0 != (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
- 0 != (poll_flag & MHD_USE_EPOLL) ? "internal thread pool with epoll" : "internal thread pool with select()");
+ 0 != (poll_flag & MHD_USE_EPOLL) ? "internal thread pool with epoll" :
+ "internal thread pool with select()");
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 64;
@@ -360,6 +428,7 @@
return 0;
}
+
static int
testExternalGet (int port)
{
@@ -385,122 +454,148 @@
unsigned int i;
char url[64];
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
- if (d == NULL)
+ port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_END);
+ if (NULL == d)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
start_timer ();
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ for (i = 0; i<ROUNDS; i++)
+ {
+ cbc.pos = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
{
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 1024;
}
- for (i=0;i<ROUNDS;i++)
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
{
- cbc.pos = 0;
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- mret = curl_multi_add_handle (multi, c);
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- }
- /* two possibilities here; as select sets are
- tiny, this makes virtually no difference
- in actual runtime right now, even though the
- number of select calls is virtually cut in half
- (and 'select' is the most expensive of our system
- calls according to 'strace') */
- if (0)
- MHD_run (d);
- else
- MHD_run_from_select (d, &rs, &ws, &es);
- }
- if (NULL != c)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- fprintf (stderr, "Timeout!?\n");
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ }
+ /* two possibilities here; as select sets are
+ tiny, this makes virtually no difference
+ in actual runtime right now, even though the
+ number of select calls is virtually cut in half
+ (and 'select' is the most expensive of our system
+ calls according to 'strace') */
+ if (0)
+ MHD_run (d);
+ else
+ MHD_run_from_select (d, &rs, &ws, &es);
}
- stop ("external select");
- if (multi != NULL)
+ if (NULL != c)
{
- curl_multi_cleanup (multi);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ fprintf (stderr, "Timeout!?\n");
}
+ }
+ stop ("external select");
+ if (multi != NULL)
+ {
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -514,33 +609,40 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
- int port = 1081;
+ int port = 1130;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (oneone)
+ port += 15;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
response = MHD_create_response_from_buffer (strlen ("/hello_world"),
- "/hello_world",
- MHD_RESPMEM_MUST_COPY);
+ "/hello_world",
+ MHD_RESPMEM_MUST_COPY);
errorCount += testExternalGet (port++);
- errorCount += testInternalGet (port++, MHD_USE_AUTO);
- errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
- errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
- errorCount += testInternalGet (port++, 0);
- errorCount += testMultithreadedGet (port++, 0);
- errorCount += testMultithreadedPoolGet (port++, 0);
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
- {
- errorCount += testInternalGet(port++, MHD_USE_POLL);
- errorCount += testMultithreadedGet(port++, MHD_USE_POLL);
- errorCount += testMultithreadedPoolGet(port++, MHD_USE_POLL);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
+ errorCount += testInternalGet (port++, 0);
+ errorCount += testMultithreadedGet (port++, 0);
+ errorCount += testMultithreadedPoolGet (port++, 0);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ errorCount += testInternalGet (port++, MHD_USE_POLL);
+ errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
}
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
{
- errorCount += testInternalGet(port++, MHD_USE_EPOLL);
- errorCount += testMultithreadedPoolGet(port++, MHD_USE_EPOLL);
+ errorCount += testInternalGet (port++, MHD_USE_EPOLL);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL);
}
+ }
MHD_destroy_response (response);
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/perf_get_concurrent.c
^
|
@@ -41,24 +41,34 @@
#include <time.h>
#include <pthread.h>
#include "gauger.h"
+#include "mhd_has_in_name.h"
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
/**
* How many rounds of operations do we do for each
* test (total number of requests will be ROUNDS * PAR).
+ * Ensure that free ports are not exhausted during test.
*/
+#if MHD_CPU_COUNT > 8
+#ifndef _WIN32
+#define ROUNDS (1 + (30000 / 12) / MHD_CPU_COUNT)
+#else /* _WIN32 */
+#define ROUNDS (1 + (3000 / 12) / MHD_CPU_COUNT)
+#endif /* _WIN32 */
+#else
#define ROUNDS 500
+#endif
/**
* How many requests do we do in parallel?
*/
-#define PAR CPU_COUNT
+#define PAR MHD_CPU_COUNT
/**
* Do we use HTTP 1.1?
@@ -92,8 +102,8 @@
struct timeval tv;
gettimeofday (&tv, NULL);
- return (((unsigned long long) tv.tv_sec * 1000LL) +
- ((unsigned long long) tv.tv_usec / 1000LL));
+ return (((unsigned long long) tv.tv_sec * 1000LL)
+ + ((unsigned long long) tv.tv_usec / 1000LL));
}
@@ -101,7 +111,7 @@
* Start the timer.
*/
static void
-start_timer()
+start_timer ()
{
start_time = now ();
}
@@ -115,30 +125,32 @@
static void
stop (const char *desc)
{
- double rps = ((double) (PAR * ROUNDS * 1000)) / ((double) (now() - start_time));
+ double rps = ((double) (PAR * ROUNDS * 1000)) / ((double) (now ()
+ - start_time));
fprintf (stderr,
- "Parallel GETs using %s: %f %s\n",
- desc,
- rps,
- "requests/s");
+ "Parallel GETs using %s: %f %s\n",
+ desc,
+ rps,
+ "requests/s");
GAUGER (desc,
- "Parallel GETs",
- rps,
- "requests/s");
+ "Parallel GETs",
+ rps,
+ "requests/s");
}
static size_t
copyBuffer (void *ptr,
- size_t size, size_t nmemb,
- void *ctx)
+ size_t size, size_t nmemb,
+ void *ctx)
{
+ (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
return size * nmemb;
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -149,15 +161,17 @@
{
static int ptr;
const char *me = cls;
- int ret;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
if (ret == MHD_NO)
@@ -172,67 +186,69 @@
CURL *c;
CURLcode errornum;
unsigned int i;
- char * const url = (char*) param;
+ char *const url = (char*) param;
- for (i=0;i<ROUNDS;i++)
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ for (i = 0; i<ROUNDS; i++)
+ {
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- return "curl error";
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
+ return "curl error";
}
+ }
+ curl_easy_cleanup (c);
return NULL;
}
static void *
-do_gets (void * param)
+do_gets (void *param)
{
int j;
pthread_t par[PAR];
char url[64];
- int port = (int)(intptr_t)param;
+ int port = (int) (intptr_t) param;
char *err = NULL;
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
-
- for (j=0;j<PAR;j++)
- {
- if (0 != pthread_create(&par[j], NULL, &thread_gets, (void*)url))
- {
- for (j--; j >= 0; j--)
- pthread_join(par[j], NULL);
- return "pthread_create error";
- }
- }
- for (j=0;j<PAR;j++)
- {
- char *ret_val;
- if (0 != pthread_join(par[j], (void**)&ret_val) ||
- NULL != ret_val)
- err = ret_val;
- }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
+ for (j = 0; j<PAR; j++)
+ {
+ if (0 != pthread_create (&par[j], NULL, &thread_gets, (void*) url))
+ {
+ for (j--; j >= 0; j--)
+ pthread_join (par[j], NULL);
+ return "pthread_create error";
+ }
+ }
+ for (j = 0; j<PAR; j++)
+ {
+ char *ret_val;
+ if ((0 != pthread_join (par[j], (void**) &ret_val)) ||
+ (NULL != ret_val) )
+ err = ret_val;
+ }
signal_done = 1;
return err;
}
@@ -242,27 +258,45 @@
testInternalGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto'" :
- (poll_flag & MHD_USE_POLL) ? "internal thread with poll()" :
- (poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll" : "internal thread with select()");
- const char * ret_val;
+ const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
+ "internal thread with 'auto'" :
+ (poll_flag & MHD_USE_POLL) ?
+ "internal thread with poll()" :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "internal thread with epoll" :
+ "internal thread with select()");
+ const char *ret_val;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
signal_done = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
start_timer ();
- ret_val = do_gets ((void*)(intptr_t)port);
- if (!ret_val)
+ ret_val = do_gets ((void*) (intptr_t) port);
+ if (! ret_val)
stop (test_desc);
MHD_stop_daemon (d);
if (ret_val)
- {
- fprintf (stderr,
- "Error performing %s test: %s\n", test_desc, ret_val);
- return 4;
- }
+ {
+ fprintf (stderr,
+ "Error performing %s test: %s\n", test_desc, ret_val);
+ return 4;
+ }
return 0;
}
@@ -271,28 +305,49 @@
testMultithreadedGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread with 'auto' and thread per connection" :
- (poll_flag & MHD_USE_POLL) ? "internal thread with poll() and thread per connection" :
- (poll_flag & MHD_USE_EPOLL) ? "internal thread with epoll and thread per connection"
- : "internal thread with select() and thread per connection");
- const char * ret_val;
+ const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
+ "internal thread with 'auto' and thread per connection"
+ :
+ (poll_flag & MHD_USE_POLL) ?
+ "internal thread with poll() and thread per connection"
+ :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "internal thread with epoll and thread per connection"
+ :
+ "internal thread with select() and thread per connection");
+ const char *ret_val;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
signal_done = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
start_timer ();
- ret_val = do_gets ((void*)(intptr_t)port);
- if (!ret_val)
+ ret_val = do_gets ((void*) (intptr_t) port);
+ if (! ret_val)
stop (test_desc);
MHD_stop_daemon (d);
if (ret_val)
- {
- fprintf (stderr,
- "Error performing %s test: %s\n", test_desc, ret_val);
- return 4;
- }
+ {
+ fprintf (stderr,
+ "Error performing %s test: %s\n", test_desc, ret_val);
+ return 4;
+ }
return 0;
}
@@ -301,28 +356,47 @@
testMultithreadedPoolGet (int port, int poll_flag)
{
struct MHD_Daemon *d;
- const char * const test_desc = ((poll_flag & MHD_USE_AUTO) ? "internal thread pool with 'auto'" :
- (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
- (poll_flag & MHD_USE_EPOLL) ? "internal thread poll with epoll" : "internal thread pool with select()");
- const char * ret_val;
+ const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
+ "internal thread pool with 'auto'" :
+ (poll_flag & MHD_USE_POLL) ?
+ "internal thread pool with poll()" :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "internal thread poll with epoll" :
+ "internal thread pool with select()");
+ const char *ret_val;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
- signal_done = 0 ;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ signal_done = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
start_timer ();
- ret_val = do_gets ((void*)(intptr_t)port);
- if (!ret_val)
+ ret_val = do_gets ((void*) (intptr_t) port);
+ if (! ret_val)
stop (test_desc);
MHD_stop_daemon (d);
if (ret_val)
- {
- fprintf (stderr,
- "Error performing %s test: %s\n", test_desc, ret_val);
- return 4;
- }
+ {
+ fprintf (stderr,
+ "Error performing %s test: %s\n", test_desc, ret_val);
+ return 4;
+ }
return 0;
}
@@ -342,56 +416,81 @@
char *ret_val;
int ret = 0;
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+
signal_done = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
- if (0 != pthread_create (&pid, NULL,
- &do_gets, (void*)(intptr_t)port))
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- MHD_stop_daemon(d);
- return 512;
+ MHD_stop_daemon (d); return 32;
}
+ port = (int) dinfo->port;
+ }
+ if (0 != pthread_create (&pid, NULL,
+ &do_gets, (void*) (intptr_t) port))
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
start_timer ();
while (0 == signal_done)
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- MHD_stop_daemon (d);
- return 4096;
- }
- tret = MHD_get_timeout (d, &tt);
- if (MHD_YES != tret) tt = 1;
- tv.tv_sec = tt / 1000;
- tv.tv_usec = 1000 * (tt % 1000);
- if (-1 == select (max + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR == errno)
- continue;
- fprintf (stderr,
- "select failed: %s\n",
- strerror (errno));
- ret |= 1024;
- break;
- }
- MHD_run_from_select(d, &rs, &ws, &es);
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tret = MHD_get_timeout (d, &tt);
+ if (MHD_YES != tret)
+ tt = 1;
+ tv.tv_sec = tt / 1000;
+ tv.tv_usec = 1000 * (tt % 1000);
+ if (-1 == select (max + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR == errno)
+ continue;
+ fprintf (stderr,
+ "select failed: %s\n",
+ strerror (errno));
+#else
+ if ((WSAEINVAL == WSAGetLastError ()) && (0 == rs.fd_count) && (0 ==
+ ws.
+ fd_count)
+ && (0 == es.fd_count) )
+ {
+ Sleep (1000);
+ continue;
+ }
+#endif
+ ret |= 1024;
+ break;
}
+ MHD_run_from_select (d, &rs, &ws, &es);
+ }
stop ("external select");
MHD_stop_daemon (d);
- if (0 != pthread_join(pid, (void**)&ret_val) ||
- NULL != ret_val)
- {
- fprintf (stderr,
- "%s\n", ret_val);
- ret |= 8;
- }
+ if ((0 != pthread_join (pid, (void**) &ret_val)) ||
+ (NULL != ret_val) )
+ {
+ fprintf (stderr,
+ "%s\n", ret_val);
+ ret |= 8;
+ }
if (ret)
fprintf (stderr, "Error performing test.\n");
return 0;
@@ -402,15 +501,19 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
- int port = 1081;
+ int port = 1100;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (oneone)
+ port += 15;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
response = MHD_create_response_from_buffer (strlen ("/hello_world"),
- "/hello_world",
- MHD_RESPMEM_MUST_COPY);
+ "/hello_world",
+ MHD_RESPMEM_MUST_COPY);
errorCount += testInternalGet (port++, 0);
errorCount += testMultithreadedGet (port++, 0);
errorCount += testMultithreadedPoolGet (port++, 0);
@@ -418,17 +521,17 @@
errorCount += testInternalGet (port++, MHD_USE_AUTO);
errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
- {
- errorCount += testInternalGet (port++, MHD_USE_POLL);
- errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
- errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
- }
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
- {
- errorCount += testInternalGet (port++, MHD_USE_EPOLL);
- errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL);
- }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ errorCount += testInternalGet (port++, MHD_USE_POLL);
+ errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ {
+ errorCount += testInternalGet (port++, MHD_USE_EPOLL);
+ errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL);
+ }
MHD_destroy_response (response);
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_add_conn.c
^
|
@@ -0,0 +1,1262 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009, 2011 Christian Grothoff
+ Copyright (C) 2020 Karlson2k (Evgeny Grin) - large rework, multithreading.
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file test_add_conn.c
+ * @brief Testcase for libmicrohttpd GET operations
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "test_helpers.h"
+#include "mhd_sockets.h" /* only macros used */
+
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif /* HAVE_LIMITS_H */
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif /* HAVE_PTHREAD_H */
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+#if MHD_CPU_COUNT > 32
+#undef MHD_CPU_COUNT
+/* Limit to reasonable value */
+#define MHD_CPU_COUNT 32
+#endif /* MHD_CPU_COUNT > 32 */
+
+/* Could be increased to facilitate debugging */
+#define TIMEOUTS_VAL 5
+
+/* Number of requests per daemon in cleanup test,
+ * the number must be more than one as the first connection
+ * will be processed and the rest will stay in the list of unprocessed */
+#define CLEANUP_NUM_REQS_PER_DAEMON 6
+
+/* Cleanup test: max number of concurrent daemons depending on maximum number
+ * of open FDs. */
+#define CLEANUP_MAX_DAEMONS(max_fds) ( ((max_fds) < 10) ? 0 : \
+ ( (((max_fds) - 10) / \
+ (CLEANUP_NUM_REQS_PER_DAEMON * 5 \
+ + 3)) ) )
+
+#define EXPECTED_URI_BASE_PATH "/hello_world"
+#define EXPECTED_URI_QUERY "a=%26&b=c"
+#define EXPECTED_URI_FULL_PATH EXPECTED_URI_BASE_PATH "?" EXPECTED_URI_QUERY
+
+/* Global parameters */
+static int oneone; /**< Use HTTP/1.1 instead of HTTP/1.0 */
+static int no_listen; /**< Start MHD daemons without listen socket */
+static int global_port; /**< MHD daemons listen port number */
+static int cleanup_test; /**< Test for final cleanup */
+static int slow_reply = 0; /**< Slowdown MHD replies */
+static int ignore_response_errors = 0; /**< Do not fail test if CURL
+ returns error */
+static int response_timeout_val = TIMEOUTS_VAL;
+static int sys_max_fds; /**< Current system limit for number of open
+ files. */
+
+
+struct CBC
+{
+ char *buf;
+ size_t pos;
+ size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+ struct CBC *cbc = ctx;
+
+ if (cbc->pos + size * nmemb > cbc->size)
+ return 0; /* overflow */
+ memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+ cbc->pos += size * nmemb;
+ return size * nmemb;
+}
+
+
+static void *
+log_cb (void *cls,
+ const char *uri,
+ struct MHD_Connection *con)
+{
+ (void) cls;
+ (void) con;
+ if (0 != strcmp (uri,
+ EXPECTED_URI_FULL_PATH))
+ {
+ fprintf (stderr,
+ "Wrong URI: `%s'\n",
+ uri);
+ _exit (22);
+ }
+ return NULL;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ const char *v;
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silence compiler warning. */
+
+ if (0 != strcasecmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ v = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "a");
+ if ( (NULL == v) ||
+ (0 != strcmp ("&",
+ v)) )
+ {
+ fprintf (stderr, "Found while looking for 'a=&': 'a=%s'\n",
+ NULL == v ? "NULL" : v);
+ _exit (17);
+ }
+ v = NULL;
+ if (MHD_YES != MHD_lookup_connection_value_n (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "b",
+ 1,
+ &v,
+ NULL))
+ {
+ fprintf (stderr, "Not found 'b' GET argument.\n");
+ _exit (18);
+ }
+ if ( (NULL == v) ||
+ (0 != strcmp ("c",
+ v)) )
+ {
+ fprintf (stderr, "Found while looking for 'b=c': 'b=%s'\n",
+ NULL == v ? "NULL" : v);
+ _exit (19);
+ }
+ if (slow_reply)
+ usleep (200000);
+
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (19);
+ }
+ return ret;
+}
+
+
+static void
+_externalErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+ if ((NULL != errDesc) && (0 != errDesc[0]))
+ fprintf (stderr, "%s", errDesc);
+ else
+ fprintf (stderr, "System or external library call failed");
+ if ((NULL != funcName) && (0 != funcName[0]))
+ fprintf (stderr, " in %s", funcName);
+ if (0 < lineNum)
+ fprintf (stderr, " at line %d", lineNum);
+
+ fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+ strerror (errno));
+#ifdef MHD_WINSOCK_SOCKETS
+ fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
+#endif /* MHD_WINSOCK_SOCKETS */
+ fflush (stderr);
+ _exit (99);
+}
+
+
+#if defined(HAVE___FUNC__)
+#define externalErrorExit(ignore) \
+ _externalErrorExit_func(NULL, __func__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+ _externalErrorExit_func(errDesc, __func__, __LINE__)
+#elif defined(HAVE___FUNCTION__)
+#define externalErrorExit(ignore) \
+ _externalErrorExit_func(NULL, __FUNCTION__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+ _externalErrorExit_func(errDesc, __FUNCTION__, __LINE__)
+#else
+#define externalErrorExit(ignore) _externalErrorExit_func(NULL, NULL, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+ _externalErrorExit_func(errDesc, NULL, __LINE__)
+#endif
+
+
+/* Static const value, indicates that result value was not set yet */
+static const int eMarker = 0xCE;
+
+
+static MHD_socket
+createListeningSocket (int *pport)
+{
+ MHD_socket skt;
+ struct sockaddr_in sin;
+ socklen_t sin_len;
+#ifdef MHD_POSIX_SOCKETS
+ static const int on = 1;
+#endif /* MHD_POSIX_SOCKETS */
+
+ skt = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (MHD_INVALID_SOCKET == skt)
+ externalErrorExitDesc ("socket() failed");
+
+#ifdef MHD_POSIX_SOCKETS
+ setsockopt (skt, SOL_SOCKET, SO_REUSEADDR, (void*) &on, sizeof (on));
+ /* Ignore possible error */
+#endif /* MHD_POSIX_SOCKETS */
+
+ memset (&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (*pport);
+ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (0 != bind (skt, (struct sockaddr*) &sin, sizeof(sin)))
+ externalErrorExitDesc ("bind() failed");
+
+ if (0 != listen (skt, SOMAXCONN))
+ externalErrorExitDesc ("listen() failed");
+
+ if (0 == *pport)
+ {
+ memset (&sin, 0, sizeof(sin));
+ sin_len = (socklen_t) sizeof(sin);
+ if (0 != getsockname (skt, (struct sockaddr *) &sin, &sin_len))
+ externalErrorExitDesc ("getsockname() failed");
+
+ if (sizeof(sin) < (size_t) sin_len)
+ externalErrorExitDesc ("getsockname() failed");
+
+ if (AF_INET != sin.sin_family)
+ externalErrorExitDesc ("getsockname() returned wrong socket family");
+
+ *pport = (int) ntohs (sin.sin_port);
+ }
+
+ return skt;
+}
+
+
+static MHD_socket
+acceptTimeLimited (MHD_socket lstn_sk, struct sockaddr *paddr,
+ socklen_t *paddr_len)
+{
+ fd_set rs;
+ struct timeval timeoutval;
+ MHD_socket accepted;
+
+ FD_ZERO (&rs);
+ FD_SET (lstn_sk, &rs);
+ timeoutval.tv_sec = TIMEOUTS_VAL;
+ timeoutval.tv_usec = 0;
+ if (1 != select (((int) lstn_sk) + 1, &rs, NULL, NULL, &timeoutval))
+ externalErrorExitDesc ("select() failed");
+
+ accepted = accept (lstn_sk, paddr, paddr_len);
+ if (MHD_INVALID_SOCKET == accepted)
+ externalErrorExitDesc ("accept() failed");
+
+ return accepted;
+}
+
+
+struct addConnParam
+{
+ struct MHD_Daemon *d;
+
+ MHD_socket lstn_sk;
+
+ MHD_socket clent_sk;
+ /* Non-zero indicate error */
+ volatile int result;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_t addConnThread;
+#endif /* HAVE_PTHREAD_H */
+};
+
+static int
+doAcceptAndAddConnInThread (struct addConnParam *p)
+{
+ struct sockaddr addr;
+ socklen_t addr_len = sizeof(addr);
+
+ p->clent_sk = acceptTimeLimited (p->lstn_sk, &addr, &addr_len);
+
+ p->result = (MHD_YES == MHD_add_connection (p->d, p->clent_sk,
+ &addr, addr_len)) ?
+ 0 : 1;
+ if (p->result)
+ fprintf (stderr, "MHD_add_connection() failed, errno=%d.\n", errno);
+ return p->result;
+}
+
+
+#ifdef HAVE_PTHREAD_H
+static void *
+doAcceptAndAddConn (void *param)
+{
+ struct addConnParam *p = param;
+
+ (void) doAcceptAndAddConnInThread (p);
+
+ return (void*) p;
+}
+
+
+static void
+startThreadAddConn (struct addConnParam *param)
+{
+ /* thread must reset this value to zero if succeed */
+ param->result = eMarker;
+
+ if (0 != pthread_create (¶m->addConnThread, NULL, &doAcceptAndAddConn,
+ (void*) param))
+ externalErrorExitDesc ("pthread_create() failed");
+}
+
+
+static int
+finishThreadAddConn (struct addConnParam *param)
+{
+ struct addConnParam *result;
+
+ if (0 != pthread_join (param->addConnThread, (void**) &result))
+ externalErrorExitDesc ("pthread_join() failed");
+
+ if (param != result)
+ abort (); /* Test used in a wrong way */
+
+ if (eMarker == param->result)
+ abort (); /* Test used in a wrong way */
+
+ return result->result;
+}
+
+
+#endif /* HAVE_PTHREAD_H */
+
+
+struct curlQueryParams
+{
+ /* Destination path for CURL query */
+ const char *queryPath;
+
+ /* Destination port for CURL query */
+ int queryPort;
+
+ /* CURL query result error flag */
+ volatile int queryError;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_t queryThread;
+#endif /* HAVE_PTHREAD_H */
+};
+
+static CURL *
+curlEasyInitForTest (const char *queryPath, int port, struct CBC *pcbc)
+{
+ CURL *c;
+
+ c = curl_easy_init ();
+ if (NULL == c)
+ {
+ fprintf (stderr, "curl_easy_init() failed.\n");
+ _exit (99);
+ }
+ if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, queryPath)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, (long) port)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
+ ©Buffer)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
+ (long) response_timeout_val)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
+ (long) response_timeout_val)) ||
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L)) ||
+ (oneone) ?
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+ CURL_HTTP_VERSION_1_1)) :
+ (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+ CURL_HTTP_VERSION_1_0)))
+ {
+ fprintf (stderr, "curl_easy_setopt() failed.\n");
+ _exit (99);
+ }
+
+ return c;
+}
+
+
+static int
+doCurlQueryInThread (struct curlQueryParams *p)
+{
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+
+ if (NULL == p->queryPath)
+ abort ();
+
+ if (0 == p->queryPort)
+ abort ();
+
+ cbc.buf = buf;
+ cbc.size = sizeof(buf);
+ cbc.pos = 0;
+
+ c = curlEasyInitForTest (p->queryPath, p->queryPort, &cbc);
+
+ errornum = curl_easy_perform (c);
+ if (ignore_response_errors)
+ {
+ p->queryError = 0;
+ curl_easy_cleanup (c);
+
+ return p->queryError;
+ }
+ if (CURLE_OK != errornum)
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ p->queryError = 2;
+ }
+ else
+ {
+ if (cbc.pos != strlen (EXPECTED_URI_BASE_PATH))
+ {
+ fprintf (stderr, "curl reports wrong size of MHD reply body data.\n");
+ p->queryError = 4;
+ }
+ else if (0 != strncmp (EXPECTED_URI_BASE_PATH, cbc.buf,
+ strlen (EXPECTED_URI_BASE_PATH)))
+ {
+ fprintf (stderr, "curl reports wrong MHD reply body data.\n");
+ p->queryError = 4;
+ }
+ else
+ p->queryError = 0;
+ }
+ curl_easy_cleanup (c);
+
+ return p->queryError;
+}
+
+
+#ifdef HAVE_PTHREAD_H
+static void *
+doCurlQuery (void *param)
+{
+ struct curlQueryParams *p = (struct curlQueryParams*) param;
+
+ (void) doCurlQueryInThread (p);
+
+ return param;
+}
+
+
+static void
+startThreadCurlQuery (struct curlQueryParams *param)
+{
+ /* thread must reset this value to zero if succeed */
+ param->queryError = eMarker;
+
+ if (0 != pthread_create (¶m->queryThread, NULL, &doCurlQuery,
+ (void*) param))
+ externalErrorExitDesc ("pthread_create() failed");
+}
+
+
+static int
+finishThreadCurlQuery (struct curlQueryParams *param)
+{
+ struct curlQueryParams *result;
+
+ if (0 != pthread_join (param->queryThread, (void**) &result))
+ externalErrorExitDesc ("pthread_join() failed");
+
+ if (param != result)
+ abort (); /* Test used in wrong way */
+
+ if (eMarker == param->queryError)
+ abort (); /* Test used in wrong way */
+
+ return result->queryError;
+}
+
+
+/* Perform test queries and shut down MHD daemon */
+static int
+performTestQueries (struct MHD_Daemon *d, int d_port)
+{
+ struct curlQueryParams qParam;
+ struct addConnParam aParam;
+ int a_port; /* Additional listening socket port */
+ int ret = 0; /* Return value */
+
+ qParam.queryPath = "http://127.0.0.1" EXPECTED_URI_FULL_PATH;
+ a_port = 0; /* auto-assign */
+
+ aParam.d = d;
+ aParam.lstn_sk = createListeningSocket (&a_port); /* Sets a_port */
+
+ /* Test of adding connection in the same thread */
+ qParam.queryError = eMarker; /* to be zeroed in new thread */
+ qParam.queryPort = a_port; /* Connect to additional socket */
+ startThreadCurlQuery (&qParam);
+ ret |= doAcceptAndAddConnInThread (&aParam);
+ ret |= finishThreadCurlQuery (&qParam);
+
+ if (! no_listen)
+ {
+ /* Test of the daemon itself can accept and process new connection. */
+ ret <<= 3; /* Remember errors for each step */
+ qParam.queryPort = d_port; /* Connect to the daemon */
+ ret |= doCurlQueryInThread (&qParam);
+ }
+
+ /* Test of adding connection in an external thread */
+ ret <<= 3; /* Remember errors for each step */
+ aParam.result = eMarker; /* to be zeroed in new thread */
+ qParam.queryPort = a_port; /* Connect to the daemon */
+ startThreadAddConn (&aParam);
+ ret |= doCurlQueryInThread (&qParam);
+ ret |= finishThreadAddConn (&aParam);
+
+ (void) MHD_socket_close_ (aParam.lstn_sk);
+ MHD_stop_daemon (d);
+
+ return ret;
+}
+
+
+/* Perform test for cleanup and shutdown MHD daemon */
+static int
+performTestCleanup (struct MHD_Daemon *d, int num_queries)
+{
+ struct curlQueryParams *qParamList;
+ struct addConnParam aParam;
+ MHD_socket lstn_sk; /* Additional listening socket */
+ MHD_socket *clntSkList;
+ int a_port; /* Additional listening socket port */
+ int i;
+ int ret = 0; /* Return value */
+
+ a_port = 0; /* auto-assign */
+
+ if (0 >= num_queries)
+ abort (); /* Test's API violation */
+
+ lstn_sk = createListeningSocket (&a_port); /* Sets a_port */
+
+ qParamList = malloc (sizeof(struct curlQueryParams) * num_queries);
+ clntSkList = malloc (sizeof(MHD_socket) * num_queries);
+ if ((NULL == qParamList) || (NULL == clntSkList))
+ externalErrorExitDesc ("malloc failed");
+
+ /* Start CURL queries */
+ for (i = 0; i < num_queries; i++)
+ {
+ qParamList[i].queryPath = "http://127.0.0.1" EXPECTED_URI_FULL_PATH;
+ qParamList[i].queryError = 0;
+ qParamList[i].queryPort = a_port;
+
+ startThreadCurlQuery (qParamList + i);
+ }
+
+ /* Accept and add required number of client sockets */
+ aParam.d = d;
+ aParam.lstn_sk = lstn_sk;
+ for (i = 0; i < num_queries; i++)
+ {
+ aParam.clent_sk = MHD_INVALID_SOCKET;
+ ret |= doAcceptAndAddConnInThread (&aParam);
+ clntSkList[i] = aParam.clent_sk;
+ }
+
+ /* Stop daemon while some of new connection are not yet
+ * processed because of slow response to the first queries. */
+ MHD_stop_daemon (d);
+ (void) MHD_socket_close_ (aParam.lstn_sk);
+
+ /* Check whether all client sockets were closed by MHD.
+ * Closure of socket by MHD indicate valid cleanup performed. */
+ for (i = 0; i < num_queries; i++)
+ {
+ if (MHD_INVALID_SOCKET != clntSkList[i])
+ { /* Check whether socket could be closed one more time. */
+ if (MHD_socket_close_ (clntSkList[i]))
+ {
+ ret |= 2;
+ fprintf (stderr, "Client socket was not closed by MHD during" \
+ "cleanup process.\n");
+ }
+ }
+ }
+
+ /* Wait for CURL threads to complete. */
+ /* Ignore soft CURL errors as many connection shouldn't get any response.
+ * Hard failures are detected in processing function. */
+ for (i = 0; i < num_queries; i++)
+ (void) finishThreadCurlQuery (qParamList + i);
+
+ free (clntSkList);
+ free (qParamList);
+
+ return ret;
+}
+
+
+#endif /* HAVE_PTHREAD_H */
+
+enum testMhdThreadsType
+{
+ testMhdThreadExternal = 0,
+ testMhdThreadInternal = MHD_USE_INTERNAL_POLLING_THREAD,
+ testMhdThreadInternalPerConnection = MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD,
+ testMhdThreadInternalPool
+};
+
+enum testMhdPollType
+{
+ testMhdPollBySelect = 0,
+ testMhdPollByPoll = MHD_USE_POLL,
+ testMhdPollByEpoll = MHD_USE_EPOLL,
+ testMhdPollAuto = MHD_USE_AUTO
+};
+
+/* Get number of threads for thread pool depending
+ * on used poll function and test type. */
+static unsigned int
+testNumThreadsForPool (enum testMhdPollType pollType)
+{
+ int numThreads = MHD_CPU_COUNT;
+ if (! cleanup_test)
+ return numThreads; /* No practical limit for non-cleanup test */
+ if (CLEANUP_MAX_DAEMONS (sys_max_fds) < numThreads)
+ numThreads = CLEANUP_MAX_DAEMONS (sys_max_fds);
+ if ((testMhdPollBySelect == pollType) &&
+ (CLEANUP_MAX_DAEMONS (FD_SETSIZE) < numThreads))
+ numThreads = CLEANUP_MAX_DAEMONS (FD_SETSIZE);
+
+ if (2 > numThreads)
+ abort ();
+ return (unsigned int) numThreads;
+}
+
+
+static struct MHD_Daemon *
+startTestMhdDaemon (enum testMhdThreadsType thrType,
+ enum testMhdPollType pollType, int *pport)
+{
+ struct MHD_Daemon *d;
+ const union MHD_DaemonInfo *dinfo;
+
+ if ( (0 == *pport) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ *pport = 1550;
+ if (oneone)
+ *pport += 1;
+ if (no_listen)
+ *pport += 2;
+ if (cleanup_test)
+ *pport += 4;
+ }
+
+ if (testMhdThreadInternalPool != thrType)
+ d = MHD_start_daemon (((int) thrType) | ((int) pollType)
+ | (thrType == testMhdThreadExternal ?
+ 0 : MHD_USE_ITC)
+ | (no_listen ? MHD_USE_NO_LISTEN_SOCKET : 0)
+ | MHD_USE_ERROR_LOG,
+ *pport, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ else
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | ((int) pollType)
+ | MHD_USE_ITC
+ | (no_listen ? MHD_USE_NO_LISTEN_SOCKET : 0)
+ | MHD_USE_ERROR_LOG,
+ *pport, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE,
+ testNumThreadsForPool (pollType),
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+
+ if (NULL == d)
+ {
+ fprintf (stderr, "Failed to start MHD daemon, errno=%d.\n", errno);
+ abort ();
+ }
+
+ if ((! no_listen) && (0 == *pport))
+ {
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ fprintf (stderr, "MHD_get_daemon_info() failed.\n");
+ abort ();
+ }
+ *pport = (int) dinfo->port;
+ }
+
+ return d;
+}
+
+
+/* Test runners */
+
+
+static int
+testExternalGet (void)
+{
+ struct MHD_Daemon *d;
+ CURL *c_d;
+ char buf_d[2048];
+ struct CBC cbc_d;
+ CURL *c_a;
+ char buf_a[2048];
+ struct CBC cbc_a;
+ CURLM *multi;
+ time_t start;
+ struct timeval tv;
+ int d_port = global_port; /* Daemon's port */
+ int a_port = 0; /* Additional listening socket port */
+ struct addConnParam aParam;
+ int ret = 0; /* Return value of the test */
+ const int c_no_listen = no_listen; /* Local const value to mute analyzer */
+
+ d = startTestMhdDaemon (testMhdThreadExternal, testMhdPollBySelect, &d_port);
+
+ aParam.d = d;
+ aParam.lstn_sk = createListeningSocket (&a_port);
+
+ multi = NULL;
+ cbc_d.buf = buf_d;
+ cbc_d.size = sizeof(buf_d);
+ cbc_d.pos = 0;
+ cbc_a.buf = buf_a;
+ cbc_a.size = sizeof(buf_a);
+ cbc_a.pos = 0;
+
+ if (cleanup_test)
+ abort (); /* Not possible with "external poll" as connections are directly
+ added to the daemon processing in the mode. */
+
+ if (! c_no_listen)
+ c_d = curlEasyInitForTest ("http://127.0.0.1" EXPECTED_URI_FULL_PATH,
+ d_port, &cbc_d);
+ else
+ c_d = NULL; /* To mute compiler warning only */
+
+ c_a = curlEasyInitForTest ("http://127.0.0.1" EXPECTED_URI_FULL_PATH,
+ a_port, &cbc_a);
+
+ multi = curl_multi_init ();
+ if (multi == NULL)
+ {
+ fprintf (stderr, "curl_multi_init() failed.\n");
+ _exit (99);
+ }
+ if (! c_no_listen)
+ {
+ if (CURLM_OK != curl_multi_add_handle (multi, c_d))
+ {
+ fprintf (stderr, "curl_multi_add_handle() failed.\n");
+ _exit (99);
+ }
+ }
+
+ if (CURLM_OK != curl_multi_add_handle (multi, c_a))
+ {
+ fprintf (stderr, "curl_multi_add_handle() failed.\n");
+ _exit (99);
+ }
+
+ start = time (NULL);
+ while (time (NULL) - start <= TIMEOUTS_VAL)
+ {
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxMhdSk;
+ int maxCurlSk;
+ int running;
+
+ maxMhdSk = MHD_INVALID_SOCKET;
+ maxCurlSk = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ if (0 == running)
+ {
+ struct CURLMsg *msg;
+ int msgLeft;
+ int totalMsgs = 0;
+ do
+ {
+ msg = curl_multi_info_read (multi, &msgLeft);
+ if (NULL == msg)
+ {
+ fprintf (stderr, "curl_multi_info_read failed, NULL returned.\n");
+ _exit (99);
+ }
+ totalMsgs++;
+ if (CURLMSG_DONE == msg->msg)
+ {
+ if (CURLE_OK != msg->data.result)
+ {
+ fprintf (stderr, "curl_multi_info_read failed, error: '%s'\n",
+ curl_easy_strerror (msg->data.result));
+ ret |= 2;
+ }
+ }
+ } while (msgLeft > 0);
+ if ((no_listen ? 1 : 2) != totalMsgs)
+ {
+ fprintf (stderr,
+ "curl_multi_info_read returned wrong "
+ "number of results (%d).\n",
+ totalMsgs);
+ _exit (99);
+ }
+ break; /* All transfers have finished. */
+ }
+ if (CURLM_OK != curl_multi_fdset (multi, &rs, &ws, &es, &maxCurlSk))
+ {
+ fprintf (stderr, "curl_multi_fdset() failed.\n");
+ _exit (99);
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk))
+ {
+ ret |= 8;
+ break;
+ }
+ FD_SET (aParam.lstn_sk, &rs);
+ if (maxMhdSk < aParam.lstn_sk)
+ maxMhdSk = aParam.lstn_sk;
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+#ifdef MHD_POSIX_SOCKETS
+ if (maxMhdSk > maxCurlSk)
+ maxCurlSk = maxMhdSk;
+#endif /* MHD_POSIX_SOCKETS */
+ if (-1 == select (maxCurlSk + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ externalErrorExitDesc ("select() failed");
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ externalErrorExitDesc ("select() failed");
+ Sleep (1000);
+#endif
+ }
+ if (FD_ISSET (aParam.lstn_sk, &rs))
+ ret |= doAcceptAndAddConnInThread (&aParam);
+
+ if (MHD_YES != MHD_run_from_select (d, &rs, &ws, &es))
+ {
+ fprintf (stderr, "MHD_run_from_select() failed.\n");
+ ret |= 1;
+ break;
+ }
+ }
+
+ MHD_stop_daemon (d);
+ (void) MHD_socket_close_ (aParam.lstn_sk);
+
+ if (! c_no_listen)
+ {
+ curl_multi_remove_handle (multi, c_d);
+ curl_easy_cleanup (c_d);
+ if (cbc_d.pos != strlen ("/hello_world"))
+ {
+ fprintf (stderr,
+ "curl reports wrong size of MHD reply body data at line %d.\n",
+ __LINE__);
+ ret |= 4;
+ }
+ if (0 != strncmp ("/hello_world", cbc_d.buf, strlen ("/hello_world")))
+ {
+ fprintf (stderr, "curl reports wrong MHD reply body data at line %d.\n",
+ __LINE__);
+ ret |= 4;
+ }
+ }
+ curl_multi_remove_handle (multi, c_a);
+ curl_easy_cleanup (c_a);
+ curl_multi_cleanup (multi);
+ if (cbc_a.pos != strlen ("/hello_world"))
+ {
+ fprintf (stderr,
+ "curl reports wrong size of MHD reply body data at line %d.\n",
+ __LINE__);
+ ret |= 4;
+ }
+ if (0 != strncmp ("/hello_world", cbc_a.buf, strlen ("/hello_world")))
+ {
+ fprintf (stderr, "curl reports wrong MHD reply body data at line %d.\n",
+ __LINE__);
+ ret |= 4;
+ }
+ return ret;
+}
+
+
+#ifdef HAVE_PTHREAD_H
+static int
+testInternalGet (enum testMhdPollType pollType)
+{
+ struct MHD_Daemon *d;
+ int d_port = global_port; /* Daemon's port */
+
+ d = startTestMhdDaemon (testMhdThreadInternal, pollType,
+ &d_port);
+ if (cleanup_test)
+ return performTestCleanup (d, CLEANUP_NUM_REQS_PER_DAEMON);
+
+ return performTestQueries (d, d_port);
+}
+
+
+static int
+testMultithreadedGet (enum testMhdPollType pollType)
+{
+ struct MHD_Daemon *d;
+ int d_port = global_port; /* Daemon's port */
+
+ d = startTestMhdDaemon (testMhdThreadInternalPerConnection, pollType,
+ &d_port);
+ if (cleanup_test)
+ abort (); /* Cannot be tested as main daemon thread cannot be slowed down
+ by slow responses, so it processes all new connections before
+ daemon could be stopped. */
+
+ return performTestQueries (d, d_port);
+}
+
+
+static int
+testMultithreadedPoolGet (enum testMhdPollType pollType)
+{
+ struct MHD_Daemon *d;
+ int d_port = global_port; /* Daemon's port */
+
+ d = startTestMhdDaemon (testMhdThreadInternalPool, pollType,
+ &d_port);
+
+ if (cleanup_test)
+ return performTestCleanup (d, CLEANUP_NUM_REQS_PER_DAEMON
+ * testNumThreadsForPool (pollType));
+ return performTestQueries (d, d_port);
+}
+
+
+static int
+testStopRace (enum testMhdPollType pollType)
+{
+ struct MHD_Daemon *d;
+ int d_port = global_port; /* Daemon's port */
+ int a_port = 0; /* Additional listening socket port */
+ struct sockaddr_in sin;
+ MHD_socket fd1;
+ MHD_socket fd2;
+ struct addConnParam aParam;
+ int ret = 0; /* Return value of the test */
+ const int c_no_listen = no_listen; /* Local const value to mute analyzer */
+
+ d = startTestMhdDaemon (testMhdThreadInternal, pollType,
+ &d_port);
+
+ if (! c_no_listen)
+ {
+ fd1 = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (MHD_INVALID_SOCKET == fd1)
+ externalErrorExitDesc ("socket() failed");
+
+ memset (&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (d_port);
+ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (connect (fd1, (struct sockaddr *) (&sin), sizeof(sin)) < 0)
+ externalErrorExitDesc ("socket() failed");
+ }
+
+ aParam.d = d;
+ aParam.lstn_sk = createListeningSocket (&a_port); /* Sets a_port */
+ startThreadAddConn (&aParam);
+
+ fd2 = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (MHD_INVALID_SOCKET == fd2)
+ externalErrorExitDesc ("socket() failed");
+ memset (&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (a_port);
+ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (connect (fd2, (struct sockaddr *) (&sin), sizeof(sin)) < 0)
+ externalErrorExitDesc ("socket() failed");
+ ret |= finishThreadAddConn (&aParam);
+
+ /* Let the thread get going. */
+ usleep (500000);
+
+ MHD_stop_daemon (d);
+
+ if (! c_no_listen)
+ (void) MHD_socket_close_ (fd1);
+ (void) MHD_socket_close_ (aParam.lstn_sk);
+ (void) MHD_socket_close_ (fd2);
+
+ return ret;
+}
+
+
+#endif /* HAVE_PTHREAD_H */
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ unsigned int test_result = 0;
+ int verbose = 0;
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ /* Whether to test MHD daemons without listening socket. */
+ no_listen = has_in_name (argv[0], "_nolisten");
+ /* Whether to test for correct final cleanup instead of
+ * of test of normal processing. */
+ cleanup_test = has_in_name (argv[0], "_cleanup");
+ /* There are almost nothing that could be tested externally
+ * for final cleanup. Cleanup test actually just tests that
+ * all added client connections were closed by MHD and
+ * nothing fails or crashes when final cleanup is performed.
+ * Mostly useful when configured with '--enable-asserts. */
+ slow_reply = cleanup_test;
+ ignore_response_errors = cleanup_test;
+#ifndef HAVE_PTHREAD_H
+ if (cleanup_test)
+ return 77; /* Cannot run without threads */
+#endif /* HAVE_PTHREAD_H */
+ verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv, "--quiet");
+ if (cleanup_test)
+ {
+#ifndef _WIN32
+ /* Find system limit for number of open FDs. */
+#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+ sys_max_fds = sysconf (_SC_OPEN_MAX);
+#else /* ! HAVE_SYSCONF || ! _SC_OPEN_MAX */
+ sys_max_fds = -1;
+#endif /* ! HAVE_SYSCONF || ! _SC_OPEN_MAX */
+ if (0 > sys_max_fds)
+ {
+#if defined(OPEN_MAX) && (0 < ((OPEN_MAX) +1))
+ sys_max_fds = OPEN_MAX;
+#else /* ! OPEN_MAX */
+ sys_max_fds = 256; /* Use reasonable value */
+#endif /* ! OPEN_MAX */
+ if (2 > CLEANUP_MAX_DAEMONS (sys_max_fds))
+ return 77; /* Multithreaded test cannot be run */
+ }
+#else /* _WIN32 */
+ sys_max_fds = 120; /* W32 has problems with ports exhaust */
+#endif /* _WIN32 */
+ }
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 99;
+ /* Could be set to non-zero value to enforce using specific port
+ * in the test */
+ global_port = 0;
+ if (! cleanup_test)
+ {
+ test_result = testExternalGet ();
+ if (test_result)
+ fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testExternalGet ().\n");
+ errorCount += test_result;
+ }
+#ifdef HAVE_PTHREAD_H
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ test_result = testInternalGet (testMhdPollBySelect);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (testMhdPollBySelect) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (testMhdPollBySelect).\n");
+ errorCount += test_result;
+ test_result = testMultithreadedPoolGet (testMhdPollBySelect);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (testMhdPollBySelect) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (testMhdPollBySelect).\n");
+ errorCount += test_result;
+ if (! cleanup_test)
+ {
+ test_result = testMultithreadedGet (testMhdPollBySelect);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedGet (testMhdPollBySelect) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (testMhdPollBySelect).\n");
+ errorCount += test_result;
+ test_result = testStopRace (testMhdPollBySelect);
+ if (test_result)
+ fprintf (stderr, "FAILED: testStopRace (testMhdPollBySelect) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testStopRace (testMhdPollBySelect).\n");
+ errorCount += test_result;
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ test_result = testInternalGet (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ test_result = testMultithreadedPoolGet (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ if (! cleanup_test)
+ {
+ test_result = testMultithreadedGet (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedGet (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ test_result = testStopRace (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr, "FAILED: testStopRace (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testStopRace (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ }
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ {
+ test_result = testInternalGet (testMhdPollByEpoll);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (testMhdPollByEpoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (testMhdPollByEpoll).\n");
+ errorCount += test_result;
+ test_result = testMultithreadedPoolGet (testMhdPollByEpoll);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (testMhdPollByEpoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (testMhdPollByEpoll).\n");
+ errorCount += test_result;
+ }
+ }
+#endif /* HAVE_PTHREAD_H */
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ errorCount);
+ else if (verbose)
+ printf ("All tests passed.\n");
+ curl_global_cleanup ();
+ return (errorCount == 0) ? 0 : 1; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_callback.c
^
|
@@ -35,49 +35,66 @@
static ssize_t
-called_twice(void *cls, uint64_t pos, char *buf, size_t max)
+called_twice (void *cls, uint64_t pos, char *buf, size_t max)
{
struct callback_closure *cls2 = cls;
+ (void) pos; /* Unused. Silence compiler warning. */
+ (void) max;
if (cls2->called == 0)
- {
- memset(buf, 0, max);
- strcat(buf, "test");
- cls2->called = 1;
- return strlen(buf);
- }
+ {
+ memcpy (buf, "test", 5);
+ cls2->called = 1;
+ return strlen (buf);
+ }
if (cls2->called == 1)
- {
- cls2->called = 2;
- return MHD_CONTENT_READER_END_OF_STREAM;
- }
- fprintf(stderr,
- "Handler called after returning END_OF_STREAM!\n");
+ {
+ cls2->called = 2;
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ }
+ fprintf (stderr,
+ "Handler called after returning END_OF_STREAM!\n");
return MHD_CONTENT_READER_END_WITH_ERROR;
}
-static int
-callback(void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **con_cls)
+static enum MHD_Result
+callback (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls)
{
- struct callback_closure *cbc = calloc(1, sizeof(struct callback_closure));
+ struct callback_closure *cbc = calloc (1, sizeof(struct callback_closure));
struct MHD_Response *r;
+ enum MHD_Result ret;
+
+ (void) cls;
+ (void) url; /* Unused. Silent compiler warning. */
+ (void) method;
+ (void) version;
+ (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size;
+ (void) con_cls; /* Unused. Silent compiler warning. */
+ if (NULL == cbc)
+ return MHD_NO;
r = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024,
- &called_twice, cbc,
- &free);
- MHD_queue_response (connection,
- MHD_HTTP_OK,
- r);
+ &called_twice, cbc,
+ &free);
+ if (NULL == r)
+ {
+ free (cbc);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ r);
MHD_destroy_response (r);
- return MHD_YES;
+ return ret;
}
@@ -87,12 +104,13 @@
size_t nmemb,
void *ctx)
{
+ (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
return size * nmemb;
}
int
-main(int argc, char **argv)
+main (int argc, char **argv)
{
struct MHD_Daemon *d;
fd_set rs;
@@ -111,99 +129,128 @@
int running;
struct timeval tv;
int extra;
+ int port;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
- d = MHD_start_daemon(0,
- 8000,
- NULL,
- NULL,
- &callback,
- NULL,
- MHD_OPTION_END);
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1140;
+
+ d = MHD_start_daemon (0,
+ port,
+ NULL,
+ NULL,
+ &callback,
+ NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 32;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 48;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:8000/");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &discard_buffer);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 1;
- }
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1;
+ }
mret = curl_multi_add_handle (multi, c);
if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ extra = 10;
+ while ( (c != NULL) || (--extra > 0) )
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&ws);
+ FD_ZERO (&rs);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ if (NULL != multi)
{
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 3;
+ }
+ }
+ if (MHD_YES !=
+ MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 2;
+ return 4;
}
- extra = 10;
- while ( (c != NULL) || (--extra > 0) )
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ if (NULL != multi)
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO(&ws);
- FD_ZERO(&rs);
- FD_ZERO(&es);
curl_multi_perform (multi, &running);
- if (NULL != multi)
- {
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 3;
- }
- }
- if (MHD_YES !=
- MHD_get_fdset(d, &rs, &ws, &es, &maxsock))
- {
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
+ c = NULL;
+ multi = NULL;
}
- if (NULL != multi)
- {
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- }
- MHD_run(d);
+ }
}
- MHD_stop_daemon(d);
+ MHD_run (d);
+ }
+ MHD_stop_daemon (d);
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_concurrent_stop.c
^
|
@@ -33,22 +33,17 @@
#include <pthread.h>
#include "gauger.h"
-#ifdef CPU_COUNT
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
-#define CPU_COUNT 40
-
-
-/**
- * How many rounds of operations do we do for each
- * test (total number of requests will be ROUNDS * PAR).
- */
-#define ROUNDS 50000
/**
* How many requests do we do in parallel?
*/
-#define PAR CPU_COUNT
+#define PAR (MHD_CPU_COUNT * 4)
/**
* Do we use HTTP 1.1?
@@ -60,17 +55,85 @@
*/
static struct MHD_Response *response;
+/**
+ * Continue generating new requests?
+ */
+static volatile int continue_requesting;
+
+/**
+ * Continue waiting in watchdog thread?
+ */
+static volatile int watchdog_continue;
+
+static const char *watchdog_obj;
+
+/**
+ * Indicate that client detected error
+ */
+static volatile CURLcode client_error;
+
+static void *
+thread_watchdog (void *param)
+{
+ int seconds_passed;
+ const int timeout_val = (int) (intptr_t) param;
+
+ seconds_passed = 0;
+ while (watchdog_continue) /* Poor threads sync, but works for testing. */
+ {
+ if (0 == sleep (1)) /* Poor accuracy, but enough for testing. */
+ seconds_passed++;
+ if (timeout_val < seconds_passed)
+ {
+ fprintf (stderr, "%s timeout expired.\n", watchdog_obj ? watchdog_obj :
+ "Watchdog");
+ fflush (stderr);
+ _exit (16);
+ }
+ }
+ return NULL;
+}
+
+
+pthread_t watchdog_tid;
+
+static void
+start_watchdog (int timeout, const char *obj_name)
+{
+ watchdog_continue = 1;
+ watchdog_obj = obj_name;
+ if (0 != pthread_create (&watchdog_tid, NULL, &thread_watchdog,
+ (void*) (intptr_t) timeout))
+ {
+ fprintf (stderr, "Failed to start watchdog.\n");
+ _exit (99);
+ }
+}
+
+
+static void
+stop_watchdog (void)
+{
+ watchdog_continue = 0;
+ if (0 != pthread_join (watchdog_tid, NULL))
+ {
+ fprintf (stderr, "Failed to stop watchdog.\n");
+ _exit (99);
+ }
+}
+
static size_t
copyBuffer (void *ptr,
- size_t size, size_t nmemb,
- void *ctx)
+ size_t size, size_t nmemb,
+ void *ctx)
{
+ (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
return size * nmemb;
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -78,20 +141,22 @@
const char *version,
const char *upload_data,
size_t *upload_data_size,
- void **unused)
+ void **usr_data)
{
- static int ptr;
+ static int marker;
const char *me = cls;
- int ret;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
- if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
- *unused = NULL;
+ if (&marker != *usr_data)
+ {
+ *usr_data = ▮
+ return MHD_YES;
+ }
+ *usr_data = NULL;
ret = MHD_queue_response (connection,
MHD_HTTP_OK,
response);
@@ -100,105 +165,95 @@
return ret;
}
-static void
-clean_curl(void * param)
-{
- if (param)
- {
- CURL * const c = *((CURL **)param);
- if (c)
- curl_easy_cleanup (c);
- }
-}
static void *
thread_gets (void *param)
{
CURL *c;
CURLcode errornum;
- unsigned int i;
- char * const url = (char*) param;
- int pth_olst;
- if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &pth_olst) ||
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &pth_olst) )
- {
- fprintf(stderr,
- "pthread_setcancelstate()/pthread_setcanceltype() failed.\n");
- _exit(99);
- }
+ char *const url = (char*) param;
- for (i=0;i<ROUNDS;i++)
+ c = NULL;
+ c = curl_easy_init ();
+ if (NULL == c)
+ {
+ fprintf (stderr, "curl_easy_init failed.\n");
+ _exit (99);
+ }
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ while (continue_requesting)
+ {
+ errornum = curl_easy_perform (c);
+ if (CURLE_OK != errornum)
{
- pthread_testcancel();
- c = NULL;
- pthread_cleanup_push(clean_curl, (void*)&c);
- c = curl_easy_init ();
- pthread_testcancel();
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
- /* NOTE: use of CONNECTTIMEOUT without also
- setting NOSIGNAL results in really weird
- crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- pthread_testcancel();
- errornum = curl_easy_perform (c);
- pthread_cleanup_pop (1);
- if (CURLE_OK != errornum)
- return NULL;
+ curl_easy_cleanup (c);
+ client_error = errornum;
+ return NULL;
}
-
+ }
+ curl_easy_cleanup (c);
return NULL;
}
+
static void *
-do_gets (void * param)
+do_gets (void *param)
{
int j;
pthread_t par[PAR];
char url[64];
- int port = (int)(intptr_t)param;
+ int port = (int) (intptr_t) param;
- sprintf(url, "http://127.0.0.1:%d/hello_world", port);
-
- for (j=0;j<PAR;j++)
- {
- if (0 != pthread_create(&par[j], NULL, &thread_gets, (void*)url))
- {
- fprintf(stderr, "pthread_create failed.\n");
- for (j--; j >= 0; j--)
- {
- pthread_cancel(par[j]);
- pthread_join(par[j], NULL);
- }
- _exit(99);
- }
- }
- sleep (1);
- for (j=0;j<PAR;j++)
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
+
+ for (j = 0; j<PAR; j++)
+ {
+ if (0 != pthread_create (&par[j], NULL, &thread_gets, (void*) url))
{
- pthread_cancel(par[j]);
- pthread_join(par[j], NULL);
+ fprintf (stderr, "pthread_create failed.\n");
+ continue_requesting = 0;
+ for (j--; j >= 0; j--)
+ {
+ pthread_join (par[j], NULL);
+ }
+ _exit (99);
}
+ }
+ (void) sleep (1);
+ for (j = 0; j<PAR; j++)
+ {
+ pthread_join (par[j], NULL);
+ }
return NULL;
}
-pthread_t start_gets(int port)
+pthread_t
+start_gets (int port)
{
pthread_t tid;
- if (0 != pthread_create(&tid, NULL, &do_gets, (void*)(intptr_t)port))
- {
- fprintf(stderr, "pthread_create failed.\n");
- _exit(99);
- }
+ continue_requesting = 1;
+ if (0 != pthread_create (&tid, NULL, &do_gets, (void*) (intptr_t) port))
+ {
+ fprintf (stderr, "pthread_create failed.\n");
+ _exit (99);
+ }
return tid;
}
@@ -209,19 +264,43 @@
{
struct MHD_Daemon *d;
pthread_t p;
+ int result;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ result = 0;
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port,
NULL, NULL,
&ahc_echo, "GET",
MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ client_error = CURLE_OK; /* clear client error state */
p = start_gets (port);
- sleep (1);
+ (void) sleep (1);
+ start_watchdog (10, "daemon_stop() in testMultithreadedGet");
+ if (CURLE_OK != client_error) /* poor sync, but enough for test */
+ {
+ result = 64;
+ fprintf (stderr, "libcurl reported at least one error: \"%s\"\n",
+ curl_easy_strerror (client_error));
+ }
MHD_stop_daemon (d);
+ stop_watchdog ();
+ continue_requesting = 0;
pthread_join (p, NULL);
- return 0;
+ return result;
}
@@ -231,20 +310,43 @@
{
struct MHD_Daemon *d;
pthread_t p;
+ int result;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
+ result = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
port,
NULL, NULL,
&ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ client_error = CURLE_OK; /* clear client error state */
p = start_gets (port);
- sleep (1);
+ (void) sleep (1);
+ start_watchdog (10, "daemon_stop() in testMultithreadedPoolGet");
+ if (CURLE_OK != client_error) /* poor sync, but enough for test */
+ {
+ result = 64;
+ fprintf (stderr, "libcurl reported at least one error: \"%s\"\n",
+ curl_easy_strerror (client_error));
+ }
MHD_stop_daemon (d);
+ stop_watchdog ();
+ continue_requesting = 0;
pthread_join (p, NULL);
- return 0;
+ return result;
}
@@ -252,17 +354,29 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
- int port = 1081;
+ int port;
+ (void) argc; /* Unused. Silent compiler warning. */
+ (void) argv; /* Unused. Silent compiler warning. */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1142;
+
+ /* Do reuse connection, otherwise all available local ports may exhausted. */
+ oneone = 1;
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((0 != port) && oneone)
+ port += 5;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
response = MHD_create_response_from_buffer (strlen ("/hello_world"),
- "/hello_world",
- MHD_RESPMEM_MUST_COPY);
- errorCount += testMultithreadedGet (port++, 0);
- errorCount += testMultithreadedPoolGet (port++, 0);
+ "/hello_world",
+ MHD_RESPMEM_MUST_COPY);
+ errorCount += testMultithreadedGet (port, 0);
+ if (0 != port)
+ port++;
+ errorCount += testMultithreadedPoolGet (port, 0);
MHD_destroy_response (response);
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_delete.c
^
|
@@ -31,16 +31,17 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
@@ -66,6 +67,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -78,7 +80,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -89,28 +92,29 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
if (0 != strcasecmp ("DELETE", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ if (*upload_data_size != 8)
+ return MHD_YES; /* not yet ready */
+ if (0 == memcmp (upload_data, "Hello123", 8))
{
- if (*upload_data_size != 8)
- return MHD_YES; /* not yet ready */
- if (0 == memcmp (upload_data, "Hello123", 8))
- {
- *upload_data_size = 0;
- }
- else
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
- *done = 1;
- return MHD_YES;
+ *upload_data_size = 0;
}
+ else
+ {
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+ *done = 1;
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url), (void*) url,
- MHD_RESPMEM_MUST_COPY);
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -127,17 +131,34 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1152;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
@@ -145,26 +166,26 @@
curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -185,17 +206,35 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1153;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
@@ -203,26 +242,26 @@
curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -233,6 +272,7 @@
return 0;
}
+
static int
testMultithreadedPoolDelete ()
{
@@ -243,18 +283,36 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1154;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
@@ -262,26 +320,26 @@
curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -317,18 +375,35 @@
struct timeval tv;
unsigned int pos = 0;
int done_flag = 0;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1154;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
@@ -336,95 +411,104 @@
curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -434,19 +518,23 @@
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalDelete ();
- errorCount += testMultithreadedDelete ();
- errorCount += testMultithreadedPoolDelete ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalDelete ();
+ errorCount += testMultithreadedDelete ();
+ errorCount += testMultithreadedPoolDelete ();
+ }
errorCount += testExternalDelete ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_digestauth.c
^
|
@@ -31,9 +31,11 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
#include <gcrypt.h>
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#ifndef WINDOWS
#include <sys/socket.h>
@@ -42,9 +44,11 @@
#include <wincrypt.h>
#endif
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
-#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+#define DENIED \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
@@ -55,8 +59,12 @@
size_t size;
};
+
static size_t
-copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+copyBuffer (void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *ctx)
{
struct CBC *cbc = ctx;
@@ -67,7 +75,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -81,43 +90,51 @@
char *username;
const char *password = "testpass";
const char *realm = "test@example.com";
- int ret;
+ enum MHD_Result ret;
+ int ret_i;
+ (void) cls; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
username = MHD_digest_auth_get_username (connection);
if ( (username == NULL) ||
(0 != strcmp (username, "testuser")) )
- {
- response = MHD_create_response_from_buffer (strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE,
- response,
- MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- ret = MHD_digest_auth_check(connection, realm,
- username,
- password,
- 300);
- free(username);
- if ( (ret == MHD_INVALID_NONCE) ||
- (ret == MHD_NO) )
- {
- response = MHD_create_response_from_buffer(strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- return MHD_NO;
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE,
- response,
- (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- response = MHD_create_response_from_buffer (strlen(PAGE),
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_auth_fail_response (connection,
+ realm,
+ MY_OPAQUE,
+ response,
+ MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ ret_i = MHD_digest_auth_check (connection,
+ realm,
+ username,
+ password,
+ 300);
+ free (username);
+ if ( (ret_i == MHD_INVALID_NONCE) ||
+ (ret_i == MHD_NO) )
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_auth_fail_response (connection,
+ realm,
+ MY_OPAQUE,
+ response,
+ (MHD_INVALID_NONCE == ret_i) ?
+ MHD_YES : MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ response = MHD_create_response_from_buffer (strlen (PAGE),
PAGE,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection,
@@ -131,58 +148,79 @@
static int
testDigestAuth ()
{
- int fd;
CURL *c;
CURLcode errornum;
struct MHD_Daemon *d;
struct CBC cbc;
- size_t len;
- size_t off = 0;
char buf[2048];
char rnd[8];
+ int port;
+ char url[128];
+#ifndef WINDOWS
+ int fd;
+ size_t len;
+ size_t off = 0;
+#endif /* ! WINDOWS */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1165;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
#ifndef WINDOWS
- fd = open("/dev/urandom", O_RDONLY);
+ fd = open ("/dev/urandom",
+ O_RDONLY);
if (-1 == fd)
- {
- fprintf(stderr, "Failed to open `%s': %s\n",
- "/dev/urandom",
- strerror(errno));
- return 1;
- }
+ {
+ fprintf (stderr,
+ "Failed to open `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ return 1;
+ }
while (off < 8)
+ {
+ len = read (fd,
+ rnd,
+ 8);
+ if (len == (size_t) -1)
{
- len = read(fd, rnd, 8);
- if (len == -1)
- {
- fprintf(stderr, "Failed to read `%s': %s\n",
- "/dev/urandom",
- strerror(errno));
- (void) close(fd);
- return 1;
- }
- off += len;
+ fprintf (stderr,
+ "Failed to read `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ (void) close (fd);
+ return 1;
}
- (void) close(fd);
+ off += len;
+ }
+ (void) close (fd);
#else
{
HCRYPTPROV cc;
BOOL b;
- b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+
+ b = CryptAcquireContext (&cc,
+ NULL,
+ NULL,
+ PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT);
if (b == 0)
{
- fprintf (stderr, "Failed to acquire crypto provider context: %lu\n",
- GetLastError ());
+ fprintf (stderr,
+ "Failed to acquire crypto provider context: %lu\n",
+ GetLastError ());
return 1;
}
- b = CryptGenRandom (cc, 8, rnd);
+ b = CryptGenRandom (cc, 8, (BYTE*) rnd);
if (b == 0)
{
- fprintf (stderr, "Failed to generate 8 random bytes: %lu\n",
- GetLastError ());
+ fprintf (stderr,
+ "Failed to generate 8 random bytes: %lu\n",
+ GetLastError ());
}
CryptReleaseContext (cc, 0);
if (b == 0)
@@ -190,35 +228,54 @@
}
#endif
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1337, NULL, NULL, &ahc_echo, PAGE,
- MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
- MHD_OPTION_NONCE_NC_SIZE, 300,
- MHD_OPTION_END);
+ port, NULL, NULL,
+ &ahc_echo, PAGE,
+ MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
+ MHD_OPTION_NONCE_NC_SIZE, 300,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+
+ dinfo = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_BIND_PORT);
+ if ( (NULL == dinfo) ||
+ (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/bar%%20foo%%3Fkey%%3Dvalue",
+ port);
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/bar%20 foo?a=bü%20");
+ curl_easy_setopt (c, CURLOPT_URL, url);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (PAGE))
@@ -233,14 +290,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif
-if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += testDigestAuth ();
if (errorCount != 0)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_digestauth_sha256.c
^
|
@@ -0,0 +1,323 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2010, 2018 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file daemontest_digestauth_sha256.c
+ * @brief Testcase for libmicrohttpd Digest Auth with SHA256
+ * @author Amr Ali
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#ifdef HAVE_GCRYPT_H
+#include <gcrypt.h>
+#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#else
+#include <wincrypt.h>
+#endif
+
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+
+#define DENIED \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+
+#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
+
+struct CBC
+{
+ char *buf;
+ size_t pos;
+ size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *ctx)
+{
+ struct CBC *cbc = ctx;
+
+ if (cbc->pos + size * nmemb > cbc->size)
+ return 0; /* overflow */
+ memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+ cbc->pos += size * nmemb;
+ return size * nmemb;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **unused)
+{
+ struct MHD_Response *response;
+ char *username;
+ const char *password = "testpass";
+ const char *realm = "test@example.com";
+ enum MHD_Result ret;
+ int ret_i;
+ (void) cls; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
+
+ username = MHD_digest_auth_get_username (connection);
+ if ( (username == NULL) ||
+ (0 != strcmp (username, "testuser")) )
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_auth_fail_response2 (connection,
+ realm,
+ MY_OPAQUE,
+ response,
+ MHD_NO,
+ MHD_DIGEST_ALG_SHA256);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ ret_i = MHD_digest_auth_check2 (connection,
+ realm,
+ username,
+ password,
+ 300,
+ MHD_DIGEST_ALG_SHA256);
+ free (username);
+ if ( (ret_i == MHD_INVALID_NONCE) ||
+ (ret_i == MHD_NO) )
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_auth_fail_response2 (connection,
+ realm,
+ MY_OPAQUE,
+ response,
+ (MHD_INVALID_NONCE == ret_i) ?
+ MHD_YES : MHD_NO,
+ MHD_DIGEST_ALG_SHA256);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ response = MHD_create_response_from_buffer (strlen (PAGE),
+ PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+static int
+testDigestAuth ()
+{
+ CURL *c;
+ CURLcode errornum;
+ struct MHD_Daemon *d;
+ struct CBC cbc;
+ char buf[2048];
+ char rnd[8];
+ int port;
+ char url[128];
+#ifndef WINDOWS
+ int fd;
+ size_t len;
+ size_t off = 0;
+#endif /* ! WINDOWS */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1167;
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+#ifndef WINDOWS
+ fd = open ("/dev/urandom",
+ O_RDONLY);
+ if (-1 == fd)
+ {
+ fprintf (stderr,
+ "Failed to open `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ return 1;
+ }
+ while (off < 8)
+ {
+ len = read (fd,
+ rnd,
+ 8);
+ if (len == (size_t) -1)
+ {
+ fprintf (stderr,
+ "Failed to read `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ (void) close (fd);
+ return 1;
+ }
+ off += len;
+ }
+ (void) close (fd);
+#else
+ {
+ HCRYPTPROV cc;
+ BOOL b;
+
+ b = CryptAcquireContext (&cc,
+ NULL,
+ NULL,
+ PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT);
+ if (b == 0)
+ {
+ fprintf (stderr,
+ "Failed to acquire crypto provider context: %lu\n",
+ GetLastError ());
+ return 1;
+ }
+ b = CryptGenRandom (cc, 8, (BYTE*) rnd);
+ if (b == 0)
+ {
+ fprintf (stderr,
+ "Failed to generate 8 random bytes: %lu\n",
+ GetLastError ());
+ }
+ CryptReleaseContext (cc, 0);
+ if (b == 0)
+ return 1;
+ }
+#endif
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL,
+ &ahc_echo, PAGE,
+ MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
+ MHD_OPTION_NONCE_NC_SIZE, 300,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+
+ dinfo = MHD_get_daemon_info (d,
+ MHD_DAEMON_INFO_BIND_PORT);
+ if ( (NULL == dinfo) ||
+ (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/bar%%20foo%%3Fkey%%3Dvalue",
+ port);
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+ curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen (PAGE))
+ return 4;
+ if (0 != strncmp (PAGE, cbc.buf, strlen (PAGE)))
+ return 8;
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ curl_version_info_data *d = curl_version_info (CURLVERSION_NOW);
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+
+#ifdef CURL_VERSION_SSPI
+ if (0 != (d->features & CURL_VERSION_SSPI))
+ return 77; /* Skip test, W32 SSPI doesn't support sha256 digest */
+#endif /* CURL_VERSION_SSPI */
+
+ /* curl added SHA256 support in 7.57 = 7.0x39 */
+ if (d->version_num < 0x073900)
+ return 77; /* skip test, curl is too old */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
+#ifdef HAVE_GCRYPT_H
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ errorCount += testDigestAuth ();
+ if (errorCount != 0)
+ fprintf (stderr, "Error (code: %u)\n", errorCount);
+ curl_global_cleanup ();
+ return errorCount != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_digestauth_with_arguments.c
^
|
@@ -30,9 +30,11 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
#include <gcrypt.h>
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#ifndef WINDOWS
#include <sys/socket.h>
@@ -41,9 +43,11 @@
#include <wincrypt.h>
#endif
-#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+#define PAGE \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
-#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+#define DENIED \
+ "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
@@ -66,7 +70,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -79,46 +84,51 @@
char *username;
const char *password = "testpass";
const char *realm = "test@example.com";
- int ret;
+ enum MHD_Result ret;
+ int ret_i;
+ (void) cls; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; (void) unused; /* Unused. Silent compiler warning. */
- username = MHD_digest_auth_get_username(connection);
+ username = MHD_digest_auth_get_username (connection);
if ( (username == NULL) ||
(0 != strcmp (username, "testuser")) )
- {
- response = MHD_create_response_from_buffer(strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE,
- response,
- MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- ret = MHD_digest_auth_check(connection, realm,
- username,
- password,
- 300);
- free(username);
- if ( (ret == MHD_INVALID_NONCE) ||
- (ret == MHD_NO) )
- {
- response = MHD_create_response_from_buffer(strlen (DENIED),
- DENIED,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- return MHD_NO;
- ret = MHD_queue_auth_fail_response(connection, realm,
- MY_OPAQUE,
- response,
- (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
- MHD_destroy_response(response);
- return ret;
- }
- response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_auth_fail_response (connection, realm,
+ MY_OPAQUE,
+ response,
+ MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ ret_i = MHD_digest_auth_check (connection, realm,
+ username,
+ password,
+ 300);
+ free (username);
+ if ( (ret_i == MHD_INVALID_NONCE) ||
+ (ret_i == MHD_NO) )
+ {
+ response = MHD_create_response_from_buffer (strlen (DENIED),
+ DENIED,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_auth_fail_response (connection, realm,
+ MY_OPAQUE,
+ response,
+ (ret_i == MHD_INVALID_NONCE) ?
+ MHD_YES : MHD_NO);
+ MHD_destroy_response (response);
+ return ret;
+ }
+ response = MHD_create_response_from_buffer (strlen (PAGE), PAGE,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
return ret;
}
@@ -126,58 +136,69 @@
static int
testDigestAuth ()
{
- int fd;
CURL *c;
CURLcode errornum;
struct MHD_Daemon *d;
struct CBC cbc;
- size_t len;
- size_t off = 0;
char buf[2048];
char rnd[8];
+ int port;
+ char url[128];
+#ifndef WINDOWS
+ int fd;
+ size_t len;
+ size_t off = 0;
+#endif /* ! WINDOWS */
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1160;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
#ifndef WINDOWS
- fd = open("/dev/urandom", O_RDONLY);
+ fd = open ("/dev/urandom", O_RDONLY);
if (-1 == fd)
- {
- fprintf(stderr, "Failed to open `%s': %s\n",
- "/dev/urandom",
- strerror(errno));
- return 1;
- }
+ {
+ fprintf (stderr, "Failed to open `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ return 1;
+ }
while (off < 8)
- {
- len = read(fd, rnd, 8);
- if (len == -1)
- {
- fprintf(stderr, "Failed to read `%s': %s\n",
- "/dev/urandom",
- strerror(errno));
- (void) close(fd);
- return 1;
- }
- off += len;
- }
- (void) close(fd);
+ {
+ len = read (fd, rnd, 8);
+ if (len == (size_t) -1)
+ {
+ fprintf (stderr,
+ "Failed to read `%s': %s\n",
+ "/dev/urandom",
+ strerror (errno));
+ (void) close (fd);
+ return 1;
+ }
+ off += len;
+ }
+ (void) close (fd);
#else
{
HCRYPTPROV cc;
BOOL b;
- b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT);
if (b == 0)
{
fprintf (stderr, "Failed to acquire crypto provider context: %lu\n",
- GetLastError ());
+ GetLastError ());
return 1;
}
- b = CryptGenRandom (cc, 8, rnd);
+ b = CryptGenRandom (cc, 8, (BYTE*) rnd);
if (b == 0)
{
fprintf (stderr, "Failed to generate 8 random bytes: %lu\n",
- GetLastError ());
+ GetLastError ());
}
CryptReleaseContext (cc, 0);
if (b == 0)
@@ -185,35 +206,49 @@
}
#endif
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1337, NULL, NULL, &ahc_echo, PAGE,
- MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
- MHD_OPTION_NONCE_NC_SIZE, 300,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, PAGE,
+ MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
+ MHD_OPTION_NONCE_NC_SIZE, 300,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/bar%%20foo%%3Fkey%%3Dvalue",
+ port);
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/foo?key=value");
+ curl_easy_setopt (c, CURLOPT_URL, url);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (PAGE))
@@ -228,13 +263,16 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += testDigestAuth ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get.c
^
|
@@ -17,14 +17,12 @@
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
-
/**
* @file test_get.c
* @brief Testcase for libmicrohttpd GET operations
* TODO: test parsing of query
* @author Christian Grothoff
*/
-
#include "MHD_config.h"
#include "platform.h"
#include <curl/curl.h>
@@ -32,9 +30,12 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "test_helpers.h"
#include "mhd_sockets.h" /* only macros used */
+#define EXPECTED_URI_PATH "/hello_world?a=%26&b=c"
+
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
@@ -47,14 +48,15 @@
#include <sys/socket.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
+static int global_port;
struct CBC
{
@@ -63,6 +65,7 @@
size_t size;
};
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -75,7 +78,27 @@
return size * nmemb;
}
-static int
+
+static void *
+log_cb (void *cls,
+ const char *uri,
+ struct MHD_Connection *con)
+{
+ (void) cls;
+ (void) con;
+ if (0 != strcmp (uri,
+ EXPECTED_URI_PATH))
+ {
+ fprintf (stderr,
+ "Wrong URI: `%s'\n",
+ uri);
+ _exit (22);
+ }
+ return NULL;
+}
+
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -87,23 +110,62 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ const char *v;
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silence compiler warning. */
if (0 != strcasecmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
+ v = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "a");
+ if ( (NULL == v) ||
+ (0 != strcmp ("&",
+ v)) )
+ {
+ fprintf (stderr, "Found while looking for 'a=&': 'a=%s'\n",
+ NULL == v ? "NULL" : v);
+ _exit (17);
+ }
+ v = NULL;
+ if (MHD_YES != MHD_lookup_connection_value_n (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "b",
+ 1,
+ &v,
+ NULL))
+ {
+ fprintf (stderr, "Not found 'b' GET argument.\n");
+ _exit (18);
+ }
+ if ( (NULL == v) ||
+ (0 != strcmp ("c",
+ v)) )
+ {
+ fprintf (stderr, "Found while looking for 'b=c': 'b=%s'\n",
+ NULL == v ? "NULL" : v);
+ _exit (19);
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
if (ret == MHD_NO)
- abort ();
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (19);
+ }
return ret;
}
@@ -117,18 +179,41 @@
struct CBC cbc;
CURLcode errornum;
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1220;
+ if (oneone)
+ global_port += 20;
+ }
+
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -138,16 +223,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -167,18 +252,42 @@
struct CBC cbc;
CURLcode errornum;
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1221;
+ if (oneone)
+ global_port += 20;
+ }
+
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -188,16 +297,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -217,19 +326,42 @@
struct CBC cbc;
CURLcode errornum;
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1222;
+ if (oneone)
+ global_port += 20;
+ }
+
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -239,16 +371,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -272,29 +404,47 @@
fd_set ws;
fd_set es;
MHD_socket maxsock;
-#ifdef MHD_WINSOCK_SOCKETS
- int maxposixs; /* Max socket number unused on W32 */
-#else /* MHD_POSIX_SOCKETS */
-#define maxposixs maxsock
-#endif /* MHD_POSIX_SOCKETS */
+ int maxposixs;
int running;
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1223;
+ if (oneone)
+ global_port += 20;
+ }
+
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
@@ -304,85 +454,98 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+#ifdef MHD_POSIX_SOCKETS
+ if (maxsock > maxposixs)
+ maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ _exit (99);
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -401,10 +564,11 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
+ memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
@@ -412,31 +576,47 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1, NULL, NULL, &ahc_echo, "GET",
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ 0, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_SOCK_ADDR, &addr,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
MHD_OPTION_END);
- if (d == NULL)
- return 32768;
-
- di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
- if (di == NULL)
- return 65536;
-
- if (0 != getsockname(di->listen_fd, (struct sockaddr *) &addr, &addr_len))
- return 131072;
-
- if (addr.sin_family != AF_INET)
- return 26214;
-
- snprintf(buf, sizeof(buf), "http://127.0.0.1:%hu/hello_world",
- ntohs(addr.sin_port));
+ if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ {
+ di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
+ if (di == NULL)
+ return 65536;
+
+ if (0 != getsockname (di->listen_fd, (struct sockaddr *) &addr, &addr_len))
+ return 131072;
+
+ if (addr.sin_family != AF_INET)
+ return 26214;
+ port = (int) ntohs (addr.sin_port);
+ }
+ else
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+
+ snprintf (buf,
+ sizeof(buf),
+ "http://127.0.0.1:%d%s",
+ port,
+ EXPECTED_URI_PATH);
c = curl_easy_init ();
curl_easy_setopt (c, CURLOPT_URL, buf);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -446,16 +626,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 524288;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 524288;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -469,90 +649,130 @@
static int
testStopRace (int poll_flag)
{
- struct sockaddr_in sin;
- MHD_socket fd;
- struct MHD_Daemon *d;
-
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
- if (d == NULL)
- return 16;
-
- fd = socket (PF_INET, SOCK_STREAM, 0);
- if (fd == MHD_INVALID_SOCKET)
- {
- fprintf(stderr, "socket error\n");
- return 256;
- }
+ struct sockaddr_in sin;
+ MHD_socket fd;
+ struct MHD_Daemon *d;
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(1081);
- sin.sin_addr.s_addr = htonl(0x7f000001);
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1224;
+ if (oneone)
+ global_port += 20;
+ }
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (fd == MHD_INVALID_SOCKET)
+ {
+ fprintf (stderr, "socket error\n");
+ return 256;
+ }
- if (connect (fd, (struct sockaddr *)(&sin), sizeof(sin)) < 0)
- {
- fprintf(stderr, "connect error\n");
- MHD_socket_close_chk_ (fd);
- return 512;
- }
+ memset (&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (global_port);
+ sin.sin_addr.s_addr = htonl (0x7f000001);
+
+ if (connect (fd, (struct sockaddr *) (&sin), sizeof(sin)) < 0)
+ {
+ fprintf (stderr, "connect error\n");
+ MHD_socket_close_chk_ (fd);
+ return 512;
+ }
- /* printf("Waiting\n"); */
- /* Let the thread get going. */
- usleep(500000);
+ /* printf("Waiting\n"); */
+ /* Let the thread get going. */
+ usleep (500000);
- /* printf("Stopping daemon\n"); */
- MHD_stop_daemon (d);
+ /* printf("Stopping daemon\n"); */
+ MHD_stop_daemon (d);
- MHD_socket_close_chk_ (fd);
+ MHD_socket_close_chk_ (fd);
- /* printf("good\n"); */
- return 0;
+ /* printf("good\n"); */
+ return 0;
}
-static int
+static enum MHD_Result
ahc_empty (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data, size_t *upload_data_size,
- void **unused)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **unused)
{
static int ptr;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls;
+ (void) url;
+ (void) url;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcasecmp ("GET", method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
if (ret == MHD_NO)
- abort ();
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (20);
+ }
return ret;
}
static int
-curlExcessFound(CURL *c, curl_infotype type, char *data, size_t size, void *cls)
+curlExcessFound (CURL *c,
+ curl_infotype type,
+ char *data,
+ size_t size,
+ void *cls)
{
static const char *excess_found = "Excess found";
const size_t str_size = strlen (excess_found);
+ (void) c; /* Unused. Silent compiler warning. */
- if (CURLINFO_TEXT == type
- && size >= str_size
- && 0 == strncmp(excess_found, data, str_size))
- *(int *)cls = 1;
+ if ((CURLINFO_TEXT == type)
+ && (size >= str_size)
+ && (0 == strncmp (excess_found, data, str_size)))
+ *(int *) cls = 1;
return 0;
}
@@ -567,21 +787,44 @@
CURLcode errornum;
int excess_found = 0;
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1225;
+ if (oneone)
+ global_port += 20;
+ }
+
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 11081, NULL, NULL, &ahc_empty, NULL, MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_empty, NULL,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 4194304;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
- curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -591,16 +834,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 8388608;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 8388608;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != 0)
@@ -615,36 +858,146 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ unsigned int test_result = 0;
+ int verbose = 0;
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ verbose = has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalGet (0);
- errorCount += testMultithreadedGet (0);
- errorCount += testMultithreadedPoolGet (0);
- errorCount += testUnknownPortGet (0);
- errorCount += testStopRace (0);
- errorCount += testExternalGet ();
- errorCount += testEmptyGet (0);
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
- {
- errorCount += testInternalGet(MHD_USE_POLL);
- errorCount += testMultithreadedGet(MHD_USE_POLL);
- errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
- errorCount += testUnknownPortGet(MHD_USE_POLL);
- errorCount += testStopRace(MHD_USE_POLL);
- errorCount += testEmptyGet(MHD_USE_POLL);
- }
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
- {
- errorCount += testInternalGet(MHD_USE_EPOLL);
- errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL);
- errorCount += testUnknownPortGet(MHD_USE_EPOLL);
- errorCount += testEmptyGet(MHD_USE_EPOLL);
- }
- if (errorCount != 0)
- fprintf (stderr, "Error (code: %u)\n", errorCount);
+ global_port = 0;
+ test_result = testExternalGet ();
+ if (test_result)
+ fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testExternalGet ().\n");
+ errorCount += test_result;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ test_result += testInternalGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (0).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (0).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedPoolGet (0) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (0).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (0).\n");
+ errorCount += test_result;
+ test_result += testStopRace (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testStopRace (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testStopRace (0).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (0).\n");
+ errorCount += test_result;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ test_result += testInternalGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testStopRace (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testStopRace (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testStopRace (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ {
+ test_result += testInternalGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ }
+ }
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ errorCount);
+ else if (verbose)
+ printf ("All tests passed.\n");
curl_global_cleanup ();
return errorCount != 0; /* 0 == pass */
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_chunked.c
^
|
@@ -40,11 +40,11 @@
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
struct CBC
@@ -54,8 +54,12 @@
size_t size;
};
+
static size_t
-copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+copyBuffer (void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *ctx)
{
struct CBC *cbc = ctx;
@@ -66,28 +70,34 @@
return size * nmemb;
}
+
/**
- * MHD content reader callback that returns
- * data in chunks.
+ * MHD content reader callback that returns data in chunks.
*/
static ssize_t
-crc (void *cls, uint64_t pos, char *buf, size_t max)
+crc (void *cls,
+ uint64_t pos,
+ char *buf,
+ size_t max)
{
struct MHD_Response **responseptr = cls;
if (pos == 128 * 10)
- {
- MHD_add_response_header (*responseptr, "Footer", "working");
- return MHD_CONTENT_READER_END_OF_STREAM;
- }
+ {
+ MHD_add_response_footer (*responseptr,
+ "Footer",
+ "working");
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ }
if (max < 128)
abort (); /* should not happen in this testcase... */
memset (buf, 'A' + (pos / 128), 128);
return 128;
}
+
/**
- * Dummy function that does nothing.
+ * Dummy function that frees the "responseptr".
*/
static void
crcf (void *ptr)
@@ -95,7 +105,8 @@
free (ptr);
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -107,28 +118,43 @@
const char *me = cls;
struct MHD_Response *response;
struct MHD_Response **responseptr;
- int ret;
+ enum MHD_Result ret;
+
+ (void) url;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
responseptr = malloc (sizeof (struct MHD_Response *));
- if (responseptr == NULL)
+ if (NULL == responseptr)
return MHD_NO;
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
1024,
- &crc, responseptr, &crcf);
+ &crc,
+ responseptr,
+ &crcf);
+ if (NULL == response)
+ {
+ free (responseptr);
+ return MHD_NO;
+ }
*responseptr = response;
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
+
static int
validate (struct CBC cbc, int ebase)
{
@@ -136,22 +162,28 @@
char buf[128];
if (cbc.pos != 128 * 10)
+ {
+ fprintf (stderr,
+ "Got %u bytes instead of 1280!\n",
+ (unsigned int) cbc.pos);
return ebase;
+ }
for (i = 0; i < 10; i++)
+ {
+ memset (buf, 'A' + i, 128);
+ if (0 != memcmp (buf, &cbc.buf[i * 128], 128))
{
- memset (buf, 'A' + i, 128);
- if (0 != memcmp (buf, &cbc.buf[i * 128], 128))
- {
- fprintf (stderr,
- "Got `%.*s'\nWant `%.*s'\n",
- 128, buf, 128, &cbc.buf[i * 128]);
- return ebase * 2;
- }
+ fprintf (stderr,
+ "Got `%.*s'\nWant `%.*s'\n",
+ 128, buf, 128, &cbc.buf[i * 128]);
+ return ebase * 2;
}
+ }
return 0;
}
+
static int
testInternalGet ()
{
@@ -160,40 +192,58 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1170;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return validate (cbc, 4);
}
+
static int
testMultithreadedGet ()
{
@@ -202,40 +252,59 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1171;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return validate (cbc, 64);
}
+
static int
testMultithreadedPoolGet ()
{
@@ -244,41 +313,60 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1172;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return validate (cbc, 64);
}
+
static int
testExternalGet ()
{
@@ -301,121 +389,150 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1173;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
return validate (cbc, 8192);
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalGet ();
- errorCount += testMultithreadedGet ();
- errorCount += testMultithreadedPoolGet ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet ();
+ errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
+ }
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_empty.c
^
|
@@ -0,0 +1,942 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009, 2011, 2019 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file test_get_empty.c
+ * @brief Testcase for libmicrohttpd GET operations returning an empty body
+ * @author Christian Grothoff
+ */
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "test_helpers.h"
+#include "mhd_sockets.h" /* only macros used */
+
+
+#define EXPECTED_URI_PATH "/hello_world?a=%26&b=c"
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+static int oneone;
+static int global_port;
+
+struct CBC
+{
+ char *buf;
+ size_t pos;
+ size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+ struct CBC *cbc = ctx;
+
+ if (cbc->pos + size * nmemb > cbc->size)
+ return 0; /* overflow */
+ memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+ cbc->pos += size * nmemb;
+ return size * nmemb;
+}
+
+
+static void *
+log_cb (void *cls,
+ const char *uri,
+ struct MHD_Connection *con)
+{
+ (void) cls;
+ (void) con;
+ if (0 != strcmp (uri,
+ EXPECTED_URI_PATH))
+ {
+ fprintf (stderr,
+ "Wrong URI: `%s'\n",
+ uri);
+ _exit (22);
+ }
+ return NULL;
+}
+
+
+static int
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ struct MHD_Response *response;
+ int ret;
+ (void) version;
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silence compiler warning. */
+
+ if (0 != strcasecmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ response = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (19);
+ }
+ return ret;
+}
+
+
+static int
+testInternalGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1220;
+ if (oneone)
+ global_port += 20;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 4;
+ return 0;
+}
+
+
+static int
+testMultithreadedGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1221;
+ if (oneone)
+ global_port += 20;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 64;
+ return 0;
+}
+
+
+static int
+testMultithreadedPoolGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1222;
+ if (oneone)
+ global_port += 20;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 64;
+ return 0;
+}
+
+
+static int
+testExternalGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLM *multi;
+ CURLMcode mret;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxsock;
+ int maxposixs;
+ int running;
+ struct CURLMsg *msg;
+ time_t start;
+ struct timeval tv;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1223;
+ if (oneone)
+ global_port += 20;
+ }
+
+ multi = NULL;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 256;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+
+
+ multi = curl_multi_init ();
+ if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+#ifdef MHD_POSIX_SOCKETS
+ if (maxsock > maxposixs)
+ maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ _exit (99);
+ Sleep (1000);
+#endif
+ }
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
+ }
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 8192;
+ return 0;
+}
+
+
+static int
+testUnknownPortGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ const union MHD_DaemonInfo *di;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ int port;
+
+ struct sockaddr_in addr;
+ socklen_t addr_len = sizeof(addr);
+ memset (&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ 0, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_SOCK_ADDR, &addr,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ {
+ di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
+ if (di == NULL)
+ return 65536;
+
+ if (0 != getsockname (di->listen_fd, (struct sockaddr *) &addr, &addr_len))
+ return 131072;
+
+ if (addr.sin_family != AF_INET)
+ return 26214;
+ port = (int) ntohs (addr.sin_port);
+ }
+ else
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+
+ snprintf (buf,
+ sizeof(buf),
+ "http://127.0.0.1:%d%s",
+ port,
+ EXPECTED_URI_PATH);
+
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, buf);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 524288;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 1048576;
+ return 0;
+}
+
+
+static int
+testStopRace (int poll_flag)
+{
+ struct sockaddr_in sin;
+ MHD_socket fd;
+ struct MHD_Daemon *d;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1224;
+ if (oneone)
+ global_port += 20;
+ }
+
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_echo, "GET",
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (fd == MHD_INVALID_SOCKET)
+ {
+ fprintf (stderr, "socket error\n");
+ return 256;
+ }
+
+ memset (&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (global_port);
+ sin.sin_addr.s_addr = htonl (0x7f000001);
+
+ if (connect (fd, (struct sockaddr *) (&sin), sizeof(sin)) < 0)
+ {
+ fprintf (stderr, "connect error\n");
+ MHD_socket_close_chk_ (fd);
+ return 512;
+ }
+
+ /* printf("Waiting\n"); */
+ /* Let the thread get going. */
+ usleep (500000);
+
+ /* printf("Stopping daemon\n"); */
+ MHD_stop_daemon (d);
+
+ MHD_socket_close_chk_ (fd);
+
+ /* printf("good\n"); */
+ return 0;
+}
+
+
+static int
+ahc_empty (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ struct MHD_Response *response;
+ int ret;
+ (void) cls;
+ (void) url;
+ (void) url;
+ (void) version; /* Unused. Silence compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcasecmp ("GET", method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ response = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ {
+ fprintf (stderr, "Failed to queue response.\n");
+ _exit (20);
+ }
+ return ret;
+}
+
+
+static int
+curlExcessFound (CURL *c, curl_infotype type, char *data, size_t size,
+ void *cls)
+{
+ static const char *excess_found = "Excess found";
+ const size_t str_size = strlen (excess_found);
+ (void) c; /* Unused. Silent compiler warning. */
+
+ if ((CURLINFO_TEXT == type)
+ && (size >= str_size)
+ && (0 == strncmp (excess_found, data, str_size)))
+ *(int *) cls = 1;
+ return 0;
+}
+
+
+static int
+testEmptyGet (int poll_flag)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLcode errornum;
+ int excess_found = 0;
+
+ if ( (0 == global_port) &&
+ (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) )
+ {
+ global_port = 1225;
+ if (oneone)
+ global_port += 20;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ global_port, NULL, NULL,
+ &ahc_empty, NULL,
+ MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 4194304;
+ if (0 == global_port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ global_port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1" EXPECTED_URI_PATH);
+ curl_easy_setopt (c, CURLOPT_PORT, (long) global_port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
+ curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
+ curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 8388608;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != 0)
+ return 16777216;
+ if (excess_found)
+ return 33554432;
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ unsigned int test_result = 0;
+ int verbose = 0;
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ verbose = has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose");
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ global_port = 0;
+ test_result = testExternalGet ();
+ if (test_result)
+ fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testExternalGet ().\n");
+ errorCount += test_result;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ test_result += testInternalGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (0).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (0).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedPoolGet (0) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (0).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (0).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (0);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (0) - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (0).\n");
+ errorCount += test_result;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ test_result += testInternalGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testMultithreadedGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (MHD_USE_POLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (MHD_USE_POLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (MHD_USE_POLL).\n");
+ errorCount += test_result;
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ {
+ test_result += testInternalGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testInternalGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testInternalGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testMultithreadedPoolGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedPoolGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testUnknownPortGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testUnknownPortGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testUnknownPortGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ test_result += testEmptyGet (MHD_USE_EPOLL);
+ if (test_result)
+ fprintf (stderr, "FAILED: testEmptyGet (MHD_USE_EPOLL) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testEmptyGet (MHD_USE_EPOLL).\n");
+ errorCount += test_result;
+ }
+ }
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ errorCount);
+ else if (verbose)
+ printf ("All tests passed.\n");
+ curl_global_cleanup ();
+ return errorCount != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_iovec.c
^
|
@@ -0,0 +1,756 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007-2021 Christian Grothoff
+ Copyright (C) 2014-2021 Evgeny Grin
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_get_iovec.c
+ * @brief Testcase for libmicrohttpd response from scatter/gather array
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ * @author Lawrence Sebald
+ */
+
+/*
+ * This test is largely derived from the test_get_sendfile.c file, with the
+ * daemon using MHD_create_response_from_iovec instead of working from an fd.
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include "mhd_sockets.h"
+#include "mhd_has_in_name.h"
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+#define TESTSTR_IOVLEN 20480
+#define TESTSTR_IOVCNT 20
+#define TESTSTR_SIZE (TESTSTR_IOVCNT * TESTSTR_IOVLEN)
+
+static int oneone;
+
+static int readbuf[TESTSTR_SIZE * 2 / sizeof(int)];
+
+struct CBC
+{
+ char *buf;
+ size_t pos;
+ size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+ struct CBC *cbc = ctx;
+
+ if (cbc->pos + size * nmemb > cbc->size)
+ _exit (7); /* overflow */
+ memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+ cbc->pos += size * nmemb;
+ return size * nmemb;
+}
+
+
+static void
+iov_free_callback (void *cls)
+{
+ free (cls);
+}
+
+
+static void
+iovncont_free_callback (void *cls)
+{
+ struct MHD_IoVec *iov = cls;
+ unsigned int i;
+
+ for (i = 0; i < TESTSTR_IOVCNT; ++i)
+ free ((void*) iov[i].iov_base);
+ free (iov);
+}
+
+
+static int
+check_read_data (const void *ptr, size_t len)
+{
+ const int *buf;
+ size_t i;
+
+ if (len % sizeof(int))
+ return -1;
+
+ buf = (const int *) ptr;
+
+ for (i = 0; i < len / sizeof(int); ++i)
+ {
+ if (buf[i] != (int) i)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ int *data;
+ struct MHD_IoVec iov[TESTSTR_IOVCNT];
+ int i;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+
+ /* Create some test data. */
+ if (NULL == (data = malloc (TESTSTR_SIZE)))
+ return MHD_NO;
+
+ for (i = 0; i < (int) (TESTSTR_SIZE / sizeof(int)); ++i)
+ {
+ data[i] = i;
+ }
+
+ for (i = 0; i < TESTSTR_IOVCNT; ++i)
+ {
+ iov[i].iov_base = data + (i * (TESTSTR_SIZE / TESTSTR_IOVCNT
+ / sizeof(int)));
+ iov[i].iov_len = TESTSTR_SIZE / TESTSTR_IOVCNT;
+ }
+
+ response = MHD_create_response_from_iovec (iov,
+ TESTSTR_IOVCNT,
+ &iov_free_callback,
+ data);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ abort ();
+ return ret;
+}
+
+
+static enum MHD_Result
+ncont_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ int *data;
+ struct MHD_IoVec *iov;
+ int i, j;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+
+ if (NULL == (iov = malloc (sizeof(struct MHD_IoVec) * TESTSTR_IOVCNT)))
+ return MHD_NO;
+
+ memset (iov, 0, sizeof(struct MHD_IoVec) * TESTSTR_IOVCNT);
+
+ /* Create some test data. */
+ for (j = TESTSTR_IOVCNT - 1; j >= 0; --j)
+ {
+ if (NULL == (data = malloc (TESTSTR_IOVLEN)))
+ goto err_out;
+
+ iov[j].iov_base = data;
+ iov[j].iov_len = TESTSTR_IOVLEN;
+
+ for (i = 0; i < (int) (TESTSTR_IOVLEN / sizeof(int)); ++i)
+ {
+ data[i] = i + (j * TESTSTR_IOVLEN / sizeof(int));
+ }
+ }
+
+ response = MHD_create_response_from_iovec (iov,
+ TESTSTR_IOVCNT,
+ &iovncont_free_callback,
+ iov);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ if (ret == MHD_NO)
+ abort ();
+ return ret;
+
+err_out:
+ for (j = 0; j < TESTSTR_IOVCNT; ++j)
+ {
+ if (NULL != iov[j].iov_base)
+ free ((void*) iov[j].iov_base);
+ }
+ free (iov);
+ return MHD_NO;
+}
+
+
+static int
+testInternalGet (bool contiguous)
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ struct CBC cbc;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1200;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = (char*) readbuf;
+ cbc.size = sizeof(readbuf);
+ cbc.pos = 0;
+
+ if (contiguous)
+ {
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ }
+ else
+ {
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ncont_echo, "GET", MHD_OPTION_END);
+ }
+
+ if (d == NULL)
+ return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != TESTSTR_SIZE)
+ return 4;
+ if (0 != check_read_data (cbc.buf, cbc.pos))
+ return 8;
+ return 0;
+}
+
+
+static int
+testMultithreadedGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ struct CBC cbc;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1201;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = (char*) readbuf;
+ cbc.size = sizeof(readbuf);
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | MHD_USE_AUTO,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != TESTSTR_SIZE)
+ return 64;
+ if (0 != check_read_data (cbc.buf, cbc.pos))
+ return 128;
+ return 0;
+}
+
+
+static int
+testMultithreadedPoolGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ struct CBC cbc;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1202;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = (char*) readbuf;
+ cbc.size = sizeof(readbuf);
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | MHD_USE_AUTO,
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system!*/
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != TESTSTR_SIZE)
+ return 64;
+ if (0 != check_read_data (cbc.buf, cbc.pos))
+ return 128;
+ return 0;
+}
+
+
+static int
+testExternalGet ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ struct CBC cbc;
+ CURLM *multi;
+ CURLMcode mret;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxsock;
+#ifdef MHD_WINSOCK_SOCKETS
+ int maxposixs; /* Max socket number unused on W32 */
+#else /* MHD_POSIX_SOCKETS */
+#define maxposixs maxsock
+#endif /* MHD_POSIX_SOCKETS */
+ int running;
+ struct CURLMsg *msg;
+ time_t start;
+ struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1203;
+ if (oneone)
+ port += 10;
+ }
+
+ multi = NULL;
+ cbc.buf = (char*) readbuf;
+ cbc.size = sizeof(readbuf);
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+
+
+ multi = curl_multi_init ();
+ if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
+ }
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
+ MHD_stop_daemon (d);
+ if (cbc.pos != TESTSTR_SIZE)
+ return 8192;
+ if (0 != check_read_data (cbc.buf, cbc.pos))
+ return 16384;
+ return 0;
+}
+
+
+static int
+testUnknownPortGet ()
+{
+ struct MHD_Daemon *d;
+ const union MHD_DaemonInfo *di;
+ CURL *c;
+ struct CBC cbc;
+ CURLcode errornum;
+ int port;
+ char buf[2048];
+
+ struct sockaddr_in addr;
+ socklen_t addr_len = sizeof(addr);
+ memset (&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ cbc.buf = (char*) readbuf;
+ cbc.size = sizeof(readbuf);
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ 0, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_SOCK_ADDR, &addr,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 32768;
+
+ if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ {
+ di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
+ if (di == NULL)
+ return 65536;
+
+ if (0 != getsockname (di->listen_fd, (struct sockaddr *) &addr, &addr_len))
+ return 131072;
+
+ if (addr.sin_family != AF_INET)
+ return 26214;
+ port = (int) ntohs (addr.sin_port);
+ }
+ else
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+
+ snprintf (buf, sizeof(buf), "http://127.0.0.1:%d/",
+ port);
+
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, buf);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ setting NOSIGNAL results in really weird
+ crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 524288;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != TESTSTR_SIZE)
+ return 1048576;
+ if (0 != check_read_data (cbc.buf, cbc.pos))
+ return 2097152;
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet (true);
+ errorCount += testInternalGet (false);
+ errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
+ errorCount += testUnknownPortGet ();
+ }
+ errorCount += testExternalGet ();
+ if (errorCount != 0)
+ fprintf (stderr, "Error (code: %u)\n", errorCount);
+ curl_global_cleanup ();
+ return errorCount != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_response_cleanup.c
^
|
@@ -35,9 +35,9 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
-#ifdef __sun
+#ifndef _WIN32
#include <signal.h>
-#endif /* __sun */
+#endif /* _WIN32 */
#ifndef WINDOWS
#include <sys/socket.h>
@@ -51,11 +51,13 @@
#include <windows.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#include "mhd_has_in_name.h"
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
#define TESTSTR "/* DO NOT CHANGE THIS LINE */"
@@ -70,13 +72,13 @@
{
pid_t ret;
- ret = fork();
+ ret = fork ();
if (ret != 0)
return ret;
execlp ("curl", "curl", "-s", "-N", "-o", "/dev/null", "-GET", url, NULL);
fprintf (stderr,
- "Failed to exec curl: %s\n",
- strerror (errno));
+ "Failed to exec curl: %s\n",
+ strerror (errno));
_exit (-1);
}
@@ -86,7 +88,7 @@
{
int status;
- //fprintf (stderr, "Killing curl\n");
+ // fprintf (stderr, "Killing curl\n");
kill (pid, SIGTERM);
waitpid (pid, &status, 0);
}
@@ -95,6 +97,8 @@
static ssize_t
push_callback (void *cls, uint64_t pos, char *buf, size_t max)
{
+ (void) cls; (void) pos; /* Unused. Silent compiler warning. */
+
if (max == 0)
return 0;
buf[0] = 'd';
@@ -105,14 +109,14 @@
static void
push_free_callback (void *cls)
{
- int *ok = cls;
+ int *ok_p = cls;
- //fprintf (stderr, "Cleanup callback called!\n");
- *ok = 0;
+ // fprintf (stderr, "Cleanup callback called!\n");
+ *ok_p = 0;
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -124,22 +128,24 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
- //fprintf (stderr, "In CB: %s!\n", method);
+ // fprintf (stderr, "In CB: %s!\n", method);
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
- 32 * 1024,
- &push_callback,
- &ok,
- &push_free_callback);
+ 32 * 1024,
+ &push_callback,
+ &ok,
+ &push_free_callback);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -153,17 +159,42 @@
{
struct MHD_Daemon *d;
pid_t curl;
+ int port;
+ char url[127];
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1180;
+ if (oneone)
+ port += 10;
+ }
ok = 1;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
- curl = fork_curl ("http://127.0.0.1:11080/");
- sleep (1);
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/",
+ port);
+ curl = fork_curl (url);
+ (void) sleep (1);
kill_curl (curl);
- sleep (1);
- // fprintf (stderr, "Stopping daemon!\n");
+ (void) sleep (1);
+ /* fprintf (stderr, "Stopping daemon!\n"); */
MHD_stop_daemon (d);
if (ok != 0)
return 2;
@@ -176,30 +207,56 @@
{
struct MHD_Daemon *d;
pid_t curl;
+ int port;
+ char url[127];
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1181;
+ if (oneone)
+ port += 10;
+ }
ok = 1;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 2,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 2,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
- //fprintf (stderr, "Forking cURL!\n");
- curl = fork_curl ("http://127.0.0.1:1081/");
- sleep (1);
- kill_curl (curl);
- sleep (1);
- curl = fork_curl ("http://127.0.0.1:1081/");
- sleep (1);
- if (ok != 0)
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- kill_curl (curl);
- MHD_stop_daemon (d);
- return 64;
+ MHD_stop_daemon (d); return 32;
}
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/",
+ port);
+ // fprintf (stderr, "Forking cURL!\n");
+ curl = fork_curl (url);
+ (void) sleep (1);
+ kill_curl (curl);
+ (void) sleep (1);
+ curl = fork_curl (url);
+ (void) sleep (1);
+ if (ok != 0)
+ {
+ kill_curl (curl);
+ MHD_stop_daemon (d);
+ return 64;
+ }
kill_curl (curl);
- sleep (1);
- //fprintf (stderr, "Stopping daemon!\n");
+ (void) sleep (1);
+ // fprintf (stderr, "Stopping daemon!\n");
MHD_stop_daemon (d);
if (ok != 0)
return 32;
@@ -213,18 +270,44 @@
{
struct MHD_Daemon *d;
pid_t curl;
+ int port;
+ char url[127];
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1182;
+ if (oneone)
+ port += 10;
+ }
ok = 1;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 64;
- curl = fork_curl ("http://127.0.0.1:1081/");
- sleep (1);
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/",
+ port);
+ curl = fork_curl (url);
+ (void) sleep (1);
kill_curl (curl);
- sleep (1);
- //fprintf (stderr, "Stopping daemon!\n");
+ (void) sleep (1);
+ // fprintf (stderr, "Stopping daemon!\n");
MHD_stop_daemon (d);
if (ok != 0)
return 128;
@@ -243,58 +326,83 @@
time_t start;
struct timeval tv;
pid_t curl;
+ int port;
+ char url[127];
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1183;
+ if (oneone)
+ port += 10;
+ }
ok = 1;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
- curl = fork_curl ("http://127.0.0.1:1082/");
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/",
+ port);
+ curl = fork_curl (url);
start = time (NULL);
while ((time (NULL) - start < 2))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
{
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (max + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- MHD_run (d);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (max + 1, &rs, &ws, &es, &tv))
+ {
+ if (EINTR != errno)
+ abort ();
}
+ MHD_run (d);
+ }
kill_curl (curl);
start = time (NULL);
while ((time (NULL) - start < 2))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
{
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (max + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- MHD_run (d);
+ MHD_stop_daemon (d);
+ return 4096;
}
- // fprintf (stderr, "Stopping daemon!\n");
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (max + 1, &rs, &ws, &es, &tv))
+ {
+ if (EINTR != errno)
+ abort ();
+ }
+ MHD_run (d);
+ }
+ /* fprintf (stderr, "Stopping daemon!\n"); */
MHD_stop_daemon (d);
if (ok != 0)
return 1024;
@@ -306,19 +414,28 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
-#ifdef __sun
- struct sigaction act;
+ (void) argc; /* Unused. Silent compiler warning. */
+#ifndef _WIN32
/* Solaris has no way to disable SIGPIPE on socket disconnect. */
- act.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &act, NULL);
-#endif /* __sun */
-
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
- errorCount += testInternalGet ();
- errorCount += testMultithreadedGet ();
- errorCount += testMultithreadedPoolGet ();
+ if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTOSUPPRESS_SIGPIPE))
+ {
+ struct sigaction act;
+
+ act.sa_handler = SIG_IGN;
+ sigaction (SIGPIPE, &act, NULL);
+ }
+#endif /* _WIN32 */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet ();
+ errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
+ }
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_sendfile.c
^
|
@@ -33,20 +33,22 @@
#include <sys/types.h>
#include <fcntl.h>
#include "mhd_sockets.h"
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <sys/socket.h>
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
-#define TESTSTR "This is the content of the test file we are sending using sendfile (if available)"
+#define TESTSTR \
+ "This is the content of the test file we are sending using sendfile (if available)"
static char *sourcefile;
@@ -73,7 +75,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -85,25 +87,27 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int fd;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
fd = open (sourcefile, O_RDONLY);
if (fd == -1)
- {
- fprintf (stderr, "Failed to open `%s': %s\n",
- sourcefile,
- strerror (errno));
- exit (1);
- }
+ {
+ fprintf (stderr, "Failed to open `%s': %s\n",
+ sourcefile,
+ strerror (errno));
+ exit (1);
+ }
response = MHD_create_response_from_fd (strlen (TESTSTR), fd);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
@@ -121,19 +125,40 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1200;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -143,16 +168,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (TESTSTR))
@@ -171,19 +196,41 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1201;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -193,16 +240,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (TESTSTR))
@@ -221,20 +268,42 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1202;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -244,16 +313,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (TESTSTR))
@@ -286,20 +355,41 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1203;
+ if (oneone)
+ port += 10;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
@@ -309,88 +399,104 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen (TESTSTR))
+ {
+ fprintf (stderr,
+ "Got %.*s instead of %s!\n",
+ (int) cbc.pos,
+ cbc.buf,
+ TESTSTR);
return 8192;
+ }
if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
return 16384;
return 0;
@@ -406,10 +512,11 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
+ memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
@@ -418,30 +525,44 @@
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1, NULL, NULL, &ahc_echo, "GET",
+ 0, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_SOCK_ADDR, &addr,
MHD_OPTION_END);
if (d == NULL)
return 32768;
- di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
- if (di == NULL)
- return 65536;
-
- if (0 != getsockname(di->listen_fd, (struct sockaddr *) &addr, &addr_len))
- return 131072;
-
- if (addr.sin_family != AF_INET)
- return 26214;
+ if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ {
+ di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
+ if (di == NULL)
+ return 65536;
+
+ if (0 != getsockname (di->listen_fd, (struct sockaddr *) &addr, &addr_len))
+ return 131072;
+
+ if (addr.sin_family != AF_INET)
+ return 26214;
+ port = (int) ntohs (addr.sin_port);
+ }
+ else
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
- snprintf(buf, sizeof(buf), "http://127.0.0.1:%hu/",
- ntohs(addr.sin_port));
+ snprintf (buf, sizeof(buf), "http://127.0.0.1:%d/",
+ port);
c = curl_easy_init ();
curl_easy_setopt (c, CURLOPT_URL, buf);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -451,16 +572,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 524288;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 524288;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen (TESTSTR))
@@ -477,34 +598,44 @@
unsigned int errorCount = 0;
const char *tmp;
FILE *f;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if ( (NULL == (tmp = getenv ("TMPDIR"))) &&
(NULL == (tmp = getenv ("TMP"))) &&
(NULL == (tmp = getenv ("TEMP"))) )
tmp = "/tmp";
sourcefile = malloc (strlen (tmp) + 32);
- sprintf (sourcefile,
- "%s/%s",
- tmp,
- "test-mhd-sendfile");
+ snprintf (sourcefile,
+ strlen (tmp) + 32,
+ "%s/%s%s",
+ tmp,
+ "test-mhd-sendfile",
+ oneone ? "11" : "");
f = fopen (sourcefile, "w");
if (NULL == f)
- {
- fprintf (stderr, "failed to write test file\n");
- free (sourcefile);
- return 1;
- }
- fwrite (TESTSTR, strlen (TESTSTR), 1, f);
+ {
+ fprintf (stderr, "failed to write test file\n");
+ free (sourcefile);
+ return 1;
+ }
+ if (1 !=
+ fwrite (TESTSTR, strlen (TESTSTR), 1, f))
+ abort ();
fclose (f);
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalGet ();
- errorCount += testMultithreadedGet ();
- errorCount += testMultithreadedPoolGet ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet ();
+ errorCount += testMultithreadedGet ();
+ errorCount += testMultithreadedPoolGet ();
+ errorCount += testUnknownPortGet ();
+ }
errorCount += testExternalGet ();
- errorCount += testUnknownPortGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
curl_global_cleanup ();
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_get_wait.c
^
|
@@ -0,0 +1,238 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009, 2011 Christian Grothoff
+ Copyright (C) 2016-2021 Karlson2k (Evgeny Grin)
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_get_wait.c
+ * @brief Test 'MHD_run_wait()' function.
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include "mhd_has_in_name.h"
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+/**
+ * How many rounds of operations do we do for each
+ * test.
+ * Check all three types of requests for HTTP/1.1:
+ * * first request, new connection;
+ * * "middle" request, existing connection with stay-alive;
+ * * final request, no data processed after.
+ */
+#define ROUNDS 3
+
+/**
+ * Do we use HTTP 1.1?
+ */
+static int oneone;
+
+/**
+ * Response to return (re-used).
+ */
+static struct MHD_Response *response;
+
+/**
+ * Set to 1 if the worker threads are done.
+ */
+static volatile int signal_done;
+
+
+static size_t
+copyBuffer (void *ptr,
+ size_t size, size_t nmemb,
+ void *ctx)
+{
+ (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
+ return size * nmemb;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (0 != strcmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ if (ret == MHD_NO)
+ abort ();
+ return ret;
+}
+
+
+static void *
+thread_gets (void *param)
+{
+ CURL *c;
+ CURLcode errornum;
+ unsigned int i;
+ char url[64];
+ int port = (int) (intptr_t) param;
+
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
+
+ c = curl_easy_init ();
+ if (NULL == c)
+ _exit (99);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ for (i = 0; i < ROUNDS; i++)
+ {
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ signal_done = 1;
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ abort ();
+ }
+ }
+ curl_easy_cleanup (c);
+ signal_done = 1;
+
+ return NULL;
+}
+
+
+static int
+testRunWaitGet (int port, int poll_flag)
+{
+ pthread_t get_tid;
+ struct MHD_Daemon *d;
+ const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
+ "MHD_USE_AUTO" :
+ (poll_flag & MHD_USE_POLL) ?
+ "MHD_USE_POLL" :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "MHD_USE_EPOLL" :
+ "select()");
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+
+ printf ("Starting MHD_run_wait() test with MHD in %s polling mode.\n",
+ test_desc);
+ signal_done = 0;
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG | poll_flag,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ abort ();
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ abort ();
+ port = (int) dinfo->port;
+ }
+
+ if (0 != pthread_create (&get_tid, NULL,
+ &thread_gets, (void*) (intptr_t) port))
+ _exit (99);
+
+ /* As another thread sets "done" flag after ending of network
+ * activity, it's required to set positive timeout value for MHD_run_wait().
+ * Alternatively, to use timeout value "-1" here, another thread should start
+ * additional connection to wake MHD after setting "done" flag. */
+ do
+ {
+ if (MHD_NO == MHD_run_wait (d, 50))
+ abort ();
+ } while (0 == signal_done);
+
+ if (0 != pthread_join (get_tid, NULL))
+ _exit (99);
+
+ MHD_stop_daemon (d);
+ printf ("Test succeeded.\n");
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ int port = 1675;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (oneone)
+ port += 5;
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ response = MHD_create_response_from_buffer (strlen ("/hello_world"),
+ "/hello_world",
+ MHD_RESPMEM_MUST_COPY);
+ testRunWaitGet (port++, 0);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ testRunWaitGet (port++, MHD_USE_EPOLL);
+ testRunWaitGet (port++, MHD_USE_AUTO);
+
+ MHD_destroy_response (response);
+ curl_global_cleanup ();
+ return 0; /* Errors produce abort() or _exit() */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_iplimit.c
^
|
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
@@ -44,11 +45,11 @@
#include <windows.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
@@ -72,7 +73,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -84,19 +86,20 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -104,6 +107,7 @@
return ret;
}
+
static int
testMultithreadedGet ()
{
@@ -112,196 +116,241 @@
int k;
unsigned int success;
unsigned int failure;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1260;
+ if (oneone)
+ port += 5;
+ }
/* Test only valid for HTTP/1.1 (uses persistent connections) */
- if (!oneone)
+ if (! oneone)
return 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL,
+ port, NULL, NULL,
&ahc_echo, "GET",
MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
for (k = 0; k < 3; ++k)
+ {
+ struct CBC cbc[3];
+ CURL *cenv[3];
+ int i;
+
+ success = 0;
+ failure = 0;
+ for (i = 0; i < 3; ++i)
+ {
+ CURL *c;
+ CURLcode errornum;
+
+ cenv[i] = c = curl_easy_init ();
+ cbc[i].buf = buf;
+ cbc[i].size = 2048;
+ cbc[i].pos = 0;
+
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+
+ errornum = curl_easy_perform (c);
+ if (CURLE_OK == errornum)
+ success++;
+ else
+ failure++;
+ }
+
+ /* Cleanup the environments */
+ for (i = 0; i < 3; ++i)
+ curl_easy_cleanup (cenv[i]);
+ if ( (2 != success) ||
+ (1 != failure) )
{
- struct CBC cbc[3];
- CURL *cenv[3];
- int i;
-
- success = 0;
- failure = 0;
- for (i = 0; i < 3; ++i)
- {
- CURL *c;
- CURLcode errornum;
-
- cenv[i] = c = curl_easy_init ();
- cbc[i].buf = buf;
- cbc[i].size = 2048;
- cbc[i].pos = 0;
-
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
-
- errornum = curl_easy_perform (c);
- if (CURLE_OK == errornum)
- success++;
- else
- failure++;
- }
-
- /* Cleanup the environments */
- for (i = 0; i < 3; ++i)
- curl_easy_cleanup (cenv[i]);
- if ( (2 != success) ||
- (1 != failure) )
+ fprintf (stderr,
+ "Unexpected number of success (%u) or failure (%u)\n",
+ success,
+ failure);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+
+ (void) sleep (2);
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (cbc[i].pos != strlen ("/hello_world"))
{
- fprintf (stderr,
- "Unexpected number of success (%u) or failure (%u)\n",
- success,
- failure);
MHD_stop_daemon (d);
- return 32;
+ return 64;
+ }
+ if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
+ {
+ MHD_stop_daemon (d);
+ return 128;
}
-
- sleep(2);
-
- for (i = 0; i < 2; ++i)
- {
- if (cbc[i].pos != strlen ("/hello_world"))
- {
- MHD_stop_daemon (d);
- return 64;
- }
- if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
- {
- MHD_stop_daemon (d);
- return 128;
- }
- }
}
+ }
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedPoolGet ()
{
struct MHD_Daemon *d;
char buf[2048];
int k;
+ int port;
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1261;
+ if (oneone)
+ port += 5;
+ }
/* Test only valid for HTTP/1.1 (uses persistent connections) */
- if (!oneone)
+ if (! oneone)
return 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, "GET",
+ port, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
for (k = 0; k < 3; ++k)
+ {
+ struct CBC cbc[3];
+ CURL *cenv[3];
+ int i;
+
+ for (i = 0; i < 3; ++i)
{
- struct CBC cbc[3];
- CURL *cenv[3];
- int i;
-
- for (i = 0; i < 3; ++i)
- {
- CURL *c;
- CURLcode errornum;
-
- cenv[i] = c = curl_easy_init ();
- cbc[i].buf = buf;
- cbc[i].size = 2048;
- cbc[i].pos = 0;
-
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
-
- errornum = curl_easy_perform (c);
- if ( ( (CURLE_OK != errornum) && (i < 2) ) ||
- ( (CURLE_OK == errornum) && (i == 2) ) )
- {
- int j;
-
- /* First 2 should succeed */
- if (i < 2)
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
-
- /* Last request should have failed */
- else
- fprintf (stderr,
- "No error on IP address over limit\n");
-
- for (j = 0; j < i; ++j)
- curl_easy_cleanup (cenv[j]);
- MHD_stop_daemon (d);
- return 32;
- }
- }
-
- /* Cleanup the environments */
- for (i = 0; i < 3; ++i)
- curl_easy_cleanup (cenv[i]);
-
- sleep(2);
-
- for (i = 0; i < 2; ++i)
- {
- if (cbc[i].pos != strlen ("/hello_world"))
- {
- MHD_stop_daemon (d);
- return 64;
- }
- if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
- {
- MHD_stop_daemon (d);
- return 128;
- }
- }
+ CURL *c;
+ CURLcode errornum;
+
+ cenv[i] = c = curl_easy_init ();
+ cbc[i].buf = buf;
+ cbc[i].size = 2048;
+ cbc[i].pos = 0;
+
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+
+ errornum = curl_easy_perform (c);
+ if ( ( (CURLE_OK != errornum) && (i < 2) ) ||
+ ( (CURLE_OK == errornum) && (i == 2) ) )
+ {
+ int j;
+
+ /* First 2 should succeed */
+ if (i < 2)
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+
+ /* Last request should have failed */
+ else
+ fprintf (stderr,
+ "No error on IP address over limit\n");
+
+ for (j = 0; j < i; ++j)
+ curl_easy_cleanup (cenv[j]);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ }
+ /* Cleanup the environments */
+ for (i = 0; i < 3; ++i)
+ curl_easy_cleanup (cenv[i]);
+ (void) sleep (2);
+
+ for (i = 0; i < 2; ++i)
+ {
+ if (cbc[i].pos != strlen ("/hello_world"))
+ {
+ MHD_stop_daemon (d);
+ return 64;
+ }
+ if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
+ {
+ MHD_stop_daemon (d);
+ return 128;
+ }
}
+
+
+ }
MHD_stop_daemon (d);
return 0;
}
+
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount |= testMultithreadedGet ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_large_put.c
^
|
@@ -38,11 +38,11 @@
#include "test_helpers.h"
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
@@ -61,34 +61,36 @@
};
char*
-alloc_init(size_t buf_size)
+alloc_init (size_t buf_size)
{
- static const char template[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz";
+ static const char template[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz";
static const size_t templ_size = sizeof(template) / sizeof(char) - 1;
char *buf;
char *fill_ptr;
size_t to_fill;
- buf = malloc(buf_size);
+ buf = malloc (buf_size);
if (NULL == buf)
return NULL;
fill_ptr = buf;
to_fill = buf_size;
while (to_fill > 0)
- {
- const size_t to_copy = to_fill > templ_size ? templ_size : to_fill;
- memcpy (fill_ptr, template, to_copy);
- fill_ptr += to_copy;
- to_fill -= to_copy;
- }
+ {
+ const size_t to_copy = to_fill > templ_size ? templ_size : to_fill;
+ memcpy (fill_ptr, template, to_copy);
+ fill_ptr += to_copy;
+ to_fill -= to_copy;
+ }
return buf;
}
+
static size_t
putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
{
- size_t *pos = (size_t *)ptr;
+ size_t *pos = (size_t *) ptr;
size_t wrt;
wrt = size * nmemb;
@@ -102,6 +104,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -114,7 +117,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -125,47 +129,48 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
static size_t processed;
+ (void) version; /* Unused. Silent compiler warning. */
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ size_t *pproc;
+ if (NULL == *pparam)
{
- size_t *pproc;
- if (NULL == *pparam)
- {
- processed = 0;
- *pparam = &processed; /* Safe as long as only one parallel request served. */
- }
- pproc = (size_t*) *pparam;
-
- if (0 == *upload_data_size)
- return MHD_YES; /* No data to process. */
-
- if (*pproc + *upload_data_size > PUT_SIZE)
- {
- fprintf (stderr, "Incoming data larger than expected.\n");
- return MHD_NO;
- }
- if ( (!incr_read) && (*upload_data_size != PUT_SIZE) )
- return MHD_YES; /* Wait until whole request is received. */
-
- if (0 != memcmp(upload_data, put_buffer + (*pproc), *upload_data_size))
- {
- fprintf (stderr, "Incoming data does not match sent data.\n");
- return MHD_NO;
- }
- *pproc += *upload_data_size;
- *upload_data_size = 0; /* Current block of data is fully processed. */
-
- if (PUT_SIZE == *pproc)
- *done = 1; /* Whole request is processed. */
- return MHD_YES;
+ processed = 0;
+ *pparam = &processed; /* Safe as long as only one parallel request served. */
}
+ pproc = (size_t*) *pparam;
+
+ if (0 == *upload_data_size)
+ return MHD_YES; /* No data to process. */
+
+ if (*pproc + *upload_data_size > PUT_SIZE)
+ {
+ fprintf (stderr, "Incoming data larger than expected.\n");
+ return MHD_NO;
+ }
+ if ( (! incr_read) && (*upload_data_size != PUT_SIZE) )
+ return MHD_YES; /* Wait until whole request is received. */
+
+ if (0 != memcmp (upload_data, put_buffer + (*pproc), *upload_data_size))
+ {
+ fprintf (stderr, "Incoming data does not match sent data.\n");
+ return MHD_NO;
+ }
+ *pproc += *upload_data_size;
+ *upload_data_size = 0; /* Current block of data is fully processed. */
+
+ if (PUT_SIZE == *pproc)
+ *done = 1; /* Whole request is processed. */
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -182,45 +187,70 @@
int done_flag = 0;
CURLcode errornum;
char buf[2048];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1270;
+ if (oneone)
+ port += 10;
+ if (incr_read)
+ port += 20;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | add_flag,
- 1080,
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | add_flag,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t)(incr_read ? 1024 : (PUT_SIZE * 4)),
- MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+ (size_t) (incr_read ? 1024 : (PUT_SIZE * 4 / 3)),
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -230,6 +260,7 @@
return 0;
}
+
static int
testPutThreadPerConn (unsigned int add_flag)
{
@@ -240,58 +271,84 @@
int done_flag = 0;
CURLcode errornum;
char buf[2048];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1271;
+ if (oneone)
+ port += 10;
+ if (incr_read)
+ port += 20;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD |
- MHD_USE_ERROR_LOG | add_flag,
- 1081,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG | add_flag,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t)(incr_read ? 1024 : (PUT_SIZE * 4)),
- MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+ (size_t) (incr_read ? 1024 : (PUT_SIZE * 4)),
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
- {
- fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
- return 64;
- }
+ {
+ fprintf (stderr, "Got invalid response `%.*s'\n", (int) cbc.pos, cbc.buf);
+ return 64;
+ }
if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
return 128;
return 0;
}
+
static int
testPutThreadPool (unsigned int add_flag)
{
@@ -302,58 +359,84 @@
int done_flag = 0;
CURLcode errornum;
char buf[2048];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1272;
+ if (oneone)
+ port += 10;
+ if (incr_read)
+ port += 20;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | add_flag,
- 1081,
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | add_flag,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t)(incr_read ? 1024 : (PUT_SIZE * 4)),
- MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+ (size_t) (incr_read ? 1024 : (PUT_SIZE * 4)),
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
- {
- fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
- return 64;
- }
+ {
+ fprintf (stderr, "Got invalid response `%.*s'\n", (int) cbc.pos, cbc.buf);
+ return 64;
+ }
if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
return 128;
return 0;
}
+
static int
testPutExternal (void)
{
@@ -378,184 +461,227 @@
size_t pos = 0;
int done_flag = 0;
char buf[2048];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1273;
+ if (oneone)
+ port += 10;
+ if (incr_read)
+ port += 20;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
multi = NULL;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t)(incr_read ? 1024 : (PUT_SIZE * 4)),
+ MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+ (size_t) (incr_read ? 1024 : (PUT_SIZE * 4)),
MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
- {
- fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
- return 8192;
- }
+ {
+ fprintf (stderr, "Got invalid response `%.*s'\n", (int) cbc.pos, cbc.buf);
+ return 8192;
+ }
if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
return 16384;
return 0;
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
unsigned int lastErr;
- oneone = has_in_name(argv[0], "11");
- incr_read = has_in_name(argv[0], "_inc");
- verbose = has_param(argc, argv, "-v");
+ oneone = has_in_name (argv[0], "11");
+ incr_read = has_in_name (argv[0], "_inc");
+ verbose = has_param (argc, argv, "-v");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 99;
put_buffer = alloc_init (PUT_SIZE);
if (NULL == put_buffer)
return 99;
- lastErr = testPutInternalThread (0);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with internal thread with select().\n");
- errorCount += lastErr;
- lastErr = testPutThreadPerConn (0);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with internal thread per connection with select().\n");
- errorCount += lastErr;
- lastErr = testPutThreadPool (0);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with thread pool per connection with select().\n");
- errorCount += lastErr;
lastErr = testPutExternal ();
- if (verbose && 0 != lastErr)
+ if (verbose && (0 != lastErr))
fprintf (stderr, "Error during testing with external select().\n");
errorCount += lastErr;
- if (MHD_is_feature_supported(MHD_FEATURE_POLL))
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ lastErr = testPutInternalThread (0);
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with internal thread with select().\n");
+ errorCount += lastErr;
+ lastErr = testPutThreadPerConn (0);
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with internal thread per connection with select().\n");
+ errorCount += lastErr;
+ lastErr = testPutThreadPool (0);
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with thread pool per connection with select().\n");
+ errorCount += lastErr;
+ if (MHD_is_feature_supported (MHD_FEATURE_POLL))
{
lastErr = testPutInternalThread (MHD_USE_POLL);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with internal thread with poll().\n");
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with internal thread with poll().\n");
errorCount += lastErr;
lastErr = testPutThreadPerConn (MHD_USE_POLL);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with internal thread per connection with poll().\n");
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with internal thread per connection with poll().\n");
errorCount += lastErr;
lastErr = testPutThreadPool (MHD_USE_POLL);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with thread pool per connection with poll().\n");
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with thread pool per connection with poll().\n");
errorCount += lastErr;
}
- if (MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+ if (MHD_is_feature_supported (MHD_FEATURE_EPOLL))
{
lastErr = testPutInternalThread (MHD_USE_EPOLL);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with internal thread with epoll.\n");
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with internal thread with epoll.\n");
errorCount += lastErr;
lastErr = testPutThreadPool (MHD_USE_EPOLL);
- if (verbose && 0 != lastErr)
- fprintf (stderr, "Error during testing with thread pool per connection with epoll.\n");
+ if (verbose && (0 != lastErr) )
+ fprintf (stderr,
+ "Error during testing with thread pool per connection with epoll.\n");
errorCount += lastErr;
}
+ }
free (put_buffer);
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_parse_cookies.c
^
|
@@ -1,4 +1,3 @@
-
/*
This file is part of libmicrohttpd
Copyright (C) 2007 Christian Grothoff
@@ -32,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
@@ -58,7 +58,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -70,16 +71,17 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
const char *hdr;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name1");
@@ -95,8 +97,8 @@
if ((hdr == NULL) || (0 != strcmp (hdr, "var4 with spaces")))
abort ();
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_PERSISTENT);
+ (void *) url,
+ MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -104,6 +106,7 @@
return ret;
}
+
static int
testExternalGet ()
{
@@ -126,20 +129,41 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1340;
+ if (oneone)
+ port += 5;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
/* note that the string below intentionally uses the
various ways cookies can be specified to exercise the
parser! Do not change! */
@@ -154,85 +178,94 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -246,9 +279,11 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += testExternalGet ();
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_patch.c
^
|
@@ -0,0 +1,511 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2020 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_patch.c
+ * @brief Testcase for libmicrohttpd PATCH operations
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "mhd_has_in_name.h"
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+ char *buf;
+ size_t pos;
+ size_t size;
+};
+
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+ unsigned int *pos = ptr;
+ unsigned int wrt;
+
+ wrt = size * nmemb;
+ if (wrt > 8 - (*pos))
+ wrt = 8 - (*pos);
+ memcpy (stream, &("Hello123"[*pos]), wrt);
+ (*pos) += wrt;
+ return wrt;
+}
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+ struct CBC *cbc = ctx;
+
+ if (cbc->pos + size * nmemb > cbc->size)
+ return 0; /* overflow */
+ memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+ cbc->pos += size * nmemb;
+ return size * nmemb;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ int *done = cls;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
+
+ if (0 != strcasecmp ("PATCH", method))
+ return MHD_NO; /* unexpected method */
+ if ((*done) == 0)
+ {
+ if (*upload_data_size != 8)
+ return MHD_YES; /* not yet ready */
+ if (0 == memcmp (upload_data, "Hello123", 8))
+ {
+ *upload_data_size = 0;
+ }
+ else
+ {
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+ *done = 1;
+ return MHD_YES;
+ }
+ response = MHD_create_response_from_buffer (strlen (url), (void*) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+static CURL *
+setup_curl (long port,
+ struct CBC *cbc,
+ unsigned int *pos)
+{
+ CURL *c;
+
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_CUSTOMREQUEST, "PATCH");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+
+ return c;
+}
+
+
+static int
+testInternalPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1450;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
+ NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+ if (d == NULL)
+ return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = setup_curl (port, &cbc, &pos);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 4;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 8;
+ return 0;
+}
+
+
+static int
+testMultithreadedPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1451;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
+ NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = setup_curl (port, &cbc, &pos);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+
+ return 0;
+}
+
+
+static int
+testMultithreadedPoolPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1452;
+ if (oneone)
+ port += 10;
+ }
+
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
+ NULL, NULL, &ahc_echo, &done_flag,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
+ if (d == NULL)
+ return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = setup_curl (port, &cbc, &pos);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 64;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 128;
+
+ return 0;
+}
+
+
+static int
+testExternalPut ()
+{
+ struct MHD_Daemon *d;
+ CURL *c;
+ char buf[2048];
+ struct CBC cbc;
+ CURLM *multi;
+ CURLMcode mret;
+ fd_set rs;
+ fd_set ws;
+ fd_set es;
+ MHD_socket maxsock;
+ int maxposixs; /* Max socket number unused on W32 */
+ int running;
+ struct CURLMsg *msg;
+ time_t start;
+ struct timeval tv;
+ unsigned int pos = 0;
+ int done_flag = 0;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1453;
+ if (oneone)
+ port += 10;
+ }
+
+ multi = NULL;
+ cbc.buf = buf;
+ cbc.size = 2048;
+ cbc.pos = 0;
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG,
+ port,
+ NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+ if (d == NULL)
+ return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = setup_curl (port, &cbc, &pos);
+
+ multi = curl_multi_init ();
+ if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+#ifdef MHD_POSIX_SOCKETS
+ if (maxsock > maxposixs)
+ maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ _exit (99);
+ Sleep (1000);
+#endif
+ }
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
+ }
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
+ MHD_stop_daemon (d);
+ if (cbc.pos != strlen ("/hello_world"))
+ return 8192;
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ return 16384;
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
+ }
+ errorCount += testExternalPut ();
+ if (errorCount != 0)
+ fprintf (stderr, "Error (code: %u)\n", errorCount);
+ curl_global_cleanup ();
+ return errorCount != 0; /* 0 == pass */
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_post.c
^
|
@@ -43,11 +43,13 @@
#include <windows.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#include "mhd_has_in_name.h"
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
#define POST_DATA "name=daniel&project=curl"
@@ -64,11 +66,12 @@
static void
completed_cb (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct MHD_PostProcessor *pp = *con_cls;
+ (void) cls; (void) connection; (void) toe; /* Unused. Silent compiler warning. */
if (NULL != pp)
MHD_destroy_post_processor (pp);
@@ -94,7 +97,7 @@
* in that it fails to support incremental processing.
* (to be fixed in the future)
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
enum MHD_ValueKind kind,
const char *key,
@@ -104,6 +107,8 @@
const char *value, uint64_t off, size_t size)
{
int *eok = cls;
+ (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; (void) off; /* Unused. Silent compiler warning. */
if ((0 == strcasecmp (key, "name")) &&
(size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size)))
@@ -115,7 +120,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -127,32 +132,33 @@
static int eok;
struct MHD_Response *response;
struct MHD_PostProcessor *pp;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) version; /* Unused. Silent compiler warning. */
if (0 != strcasecmp ("POST", method))
- {
- printf ("METHOD: %s\n", method);
- return MHD_NO; /* unexpected method */
- }
+ {
+ printf ("METHOD: %s\n", method);
+ return MHD_NO; /* unexpected method */
+ }
pp = *unused;
if (pp == NULL)
- {
- eok = 0;
- pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
- *unused = pp;
- }
+ {
+ eok = 0;
+ pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+ *unused = pp;
+ }
MHD_post_process (pp, upload_data, *upload_data_size);
if ((eok == 3) && (0 == *upload_data_size))
- {
- response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- MHD_destroy_post_processor (pp);
- *unused = NULL;
- return ret;
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ MHD_destroy_post_processor (pp);
+ *unused = NULL;
+ return ret;
+ }
*upload_data_size = 0;
return MHD_YES;
}
@@ -166,43 +172,64 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1370;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -212,6 +239,7 @@
return 0;
}
+
static int
testMultithreadedPost ()
{
@@ -220,43 +248,65 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1371;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -266,6 +316,7 @@
return 0;
}
+
static int
testMultithreadedPoolPost ()
{
@@ -274,44 +325,65 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1372;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -321,6 +393,7 @@
return 0;
}
+
static int
testExternalPost ()
{
@@ -343,112 +416,143 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1373;
+ if (oneone)
+ port += 10;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- } MHD_run (d);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -458,45 +562,48 @@
}
-static int
+static enum MHD_Result
ahc_cancel (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data, size_t *upload_data_size,
- void **unused)
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
{
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcasecmp ("POST", method))
- {
- fprintf (stderr,
- "Unexpected method `%s'\n", method);
- return MHD_NO;
- }
+ {
+ fprintf (stderr,
+ "Unexpected method `%s'\n", method);
+ return MHD_NO;
+ }
if (*unused == NULL)
- {
- *unused = "wibble";
- /* We don't want the body. Send a 500. */
- response = MHD_create_response_from_buffer (0, NULL,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response(connection, 500, response);
- if (ret != MHD_YES)
- fprintf(stderr, "Failed to queue response\n");
- MHD_destroy_response(response);
- return ret;
- }
+ {
+ *unused = "wibble";
+ /* We don't want the body. Send a 500. */
+ response = MHD_create_response_from_buffer (0, NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, 500, response);
+ if (ret != MHD_YES)
+ fprintf (stderr, "Failed to queue response\n");
+ MHD_destroy_response (response);
+ return ret;
+ }
else
- {
- fprintf(stderr,
- "In ahc_cancel again. This should not happen.\n");
- return MHD_NO;
- }
+ {
+ fprintf (stderr,
+ "In ahc_cancel again. This should not happen.\n");
+ return MHD_NO;
+ }
}
+
struct CRBC
{
const char *buffer;
@@ -506,7 +613,7 @@
static size_t
-readBuffer(void *p, size_t size, size_t nmemb, void *opaque)
+readBuffer (void *p, size_t size, size_t nmemb, void *opaque)
{
struct CRBC *data = opaque;
size_t required = size * nmemb;
@@ -515,18 +622,18 @@
if (required > left)
required = left;
- memcpy(p, data->buffer + data->pos, required);
+ memcpy (p, data->buffer + data->pos, required);
data->pos += required;
- return required/size;
+ return required / size;
}
static size_t
-slowReadBuffer(void *p, size_t size, size_t nmemb, void *opaque)
+slowReadBuffer (void *p, size_t size, size_t nmemb, void *opaque)
{
- sleep(1);
- return readBuffer(p, size, nmemb, opaque);
+ (void) sleep (1);
+ return readBuffer (p, size, nmemb, opaque);
}
@@ -538,7 +645,7 @@
static int
-testMultithreadedPostCancelPart(int flags)
+testMultithreadedPostCancelPart (int flags)
{
struct MHD_Daemon *d;
CURL *c;
@@ -550,109 +657,136 @@
CURLcode cc;
int result = 0;
struct CRBC crbc;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1374;
+ if (oneone)
+ port += 10;
+ }
/* Don't test features that aren't available with HTTP/1.0 in
* HTTP/1.0 mode. */
- if (!oneone && (flags & (FLAG_EXPECT_CONTINUE | FLAG_CHUNKED)))
+ if (! oneone && (flags & (FLAG_EXPECT_CONTINUE | FLAG_CHUNKED)))
return 0;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_cancel, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_cancel, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 32768;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
crbc.buffer = "Test content";
- crbc.size = strlen(crbc.buffer);
+ crbc.size = strlen (crbc.buffer);
crbc.pos = 0;
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, (flags & FLAG_SLOW_READ) ? &slowReadBuffer : &readBuffer);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, (flags & FLAG_SLOW_READ) ?
+ &slowReadBuffer : &readBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &crbc);
curl_easy_setopt (c, CURLOPT_POSTFIELDS, NULL);
curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, crbc.size);
curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (flags & FLAG_CHUNKED)
- headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
- if (!(flags & FLAG_FORM_DATA))
- headers = curl_slist_append(headers, "Content-Type: application/octet-stream");
+ headers = curl_slist_append (headers, "Transfer-Encoding: chunked");
+ if (! (flags & FLAG_FORM_DATA))
+ headers = curl_slist_append (headers,
+ "Content-Type: application/octet-stream");
if (flags & FLAG_EXPECT_CONTINUE)
- headers = curl_slist_append(headers, "Expect: 100-Continue");
- curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers);
+ headers = curl_slist_append (headers, "Expect: 100-Continue");
+ curl_easy_setopt (c, CURLOPT_HTTPHEADER, headers);
if (CURLE_HTTP_RETURNED_ERROR != (errornum = curl_easy_perform (c)))
- {
+ {
#ifdef _WIN32
- curl_version_info_data *curlverd = curl_version_info(CURLVERSION_NOW);
- if (0 != (flags & FLAG_SLOW_READ) && CURLE_RECV_ERROR == errornum &&
- (curlverd == NULL || curlverd->ares_num < 0x073100) )
- { /* libcurl up to version 7.49.0 didn't have workaround for WinSock bug */
- fprintf (stderr, "Ignored curl_easy_perform expected failure on W32 with \"slow read\".\n");
- result = 0;
- }
- else
+ curl_version_info_data *curlverd = curl_version_info (CURLVERSION_NOW);
+ if ((0 != (flags & FLAG_SLOW_READ)) && (CURLE_RECV_ERROR == errornum) &&
+ ((curlverd == NULL) || (curlverd->ares_num < 0x073100) ) )
+ { /* libcurl up to version 7.49.0 didn't have workaround for WinSock bug */
+ fprintf (stderr,
+ "Ignored curl_easy_perform expected failure on W32 with \"slow read\".\n");
+ result = 0;
+ }
+ else
#else /* ! _WIN32 */
- if(1)
+ if (1)
#endif /* ! _WIN32 */
- {
- fprintf (stderr,
- "flibbet curl_easy_perform didn't fail as expected: `%s' %d\n",
- curl_easy_strerror (errornum), errornum);
- result = 65536;
- }
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- curl_slist_free_all(headers);
- return result;
- }
-
- if (CURLE_OK != (cc = curl_easy_getinfo(c, CURLINFO_RESPONSE_CODE, &response_code)))
{
- fprintf(stderr, "curl_easy_getinfo failed: '%s'\n", curl_easy_strerror(errornum));
+ fprintf (stderr,
+ "flibbet curl_easy_perform didn't fail as expected: `%s' %d\n",
+ curl_easy_strerror (errornum), errornum);
result = 65536;
}
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ curl_slist_free_all (headers);
+ return result;
+ }
+
+ if (CURLE_OK != (cc = curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE,
+ &response_code)))
+ {
+ fprintf (stderr, "curl_easy_getinfo failed: '%s'\n", curl_easy_strerror (
+ errornum));
+ result = 65536;
+ }
+
+ if (! result && (response_code != 500))
+ {
+ fprintf (stderr, "Unexpected response code: %ld\n", response_code);
+ result = 131072;
+ }
- if (!result && (response_code != 500))
- {
- fprintf(stderr, "Unexpected response code: %ld\n", response_code);
- result = 131072;
- }
-
- if (!result && (cbc.pos != 0))
+ if (! result && (cbc.pos != 0))
result = 262144;
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- curl_slist_free_all(headers);
+ curl_slist_free_all (headers);
return result;
}
static int
-testMultithreadedPostCancel()
+testMultithreadedPostCancel ()
{
int result = 0;
int flags;
- for(flags = 0; flags < FLAG_COUNT; ++flags)
- result |= testMultithreadedPostCancelPart(flags);
+ for (flags = 0; flags < FLAG_COUNT; ++flags)
+ result |= testMultithreadedPostCancelPart (flags);
return result;
}
@@ -661,15 +795,20 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testMultithreadedPostCancel ();
- errorCount += testInternalPost ();
- errorCount += testMultithreadedPost ();
- errorCount += testMultithreadedPoolPost ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testMultithreadedPostCancel ();
+ errorCount += testInternalPost ();
+ errorCount += testMultithreadedPost ();
+ errorCount += testMultithreadedPoolPost ();
+ }
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_post_loop.c
^
|
@@ -31,22 +31,29 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <gauger.h>
+#include "gauger.h"
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
-#define POST_DATA "<?xml version='1.0' ?>\n<xml>\n<data-id>1</data-id>\n</xml>\n"
+#define POST_DATA \
+ "<?xml version='1.0' ?>\n<xml>\n<data-id>1</data-id>\n</xml>\n"
+#ifndef __APPLE__
#define LOOPCOUNT 1000
+#else /* __APPLE__ */
+/* FIXME: macOS may fail in this test with "unable to connect". Investigate deeper? */
+#define LOOPCOUNT 200
+#endif /* __APPLE__ */
static int oneone;
@@ -69,7 +76,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -80,24 +88,26 @@
{
static int marker;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) url; (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp ("POST", method))
- {
- printf ("METHOD: %s\n", method);
- return MHD_NO; /* unexpected method */
- }
+ {
+ printf ("METHOD: %s\n", method);
+ return MHD_NO; /* unexpected method */
+ }
if ((*mptr != NULL) && (0 == *upload_data_size))
- {
- if (*mptr != &marker)
- abort ();
- response = MHD_create_response_from_buffer (2, "OK",
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- *mptr = NULL;
- return ret;
- }
+ {
+ if (*mptr != &marker)
+ abort ();
+ response = MHD_create_response_from_buffer (2, "OK",
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ *mptr = NULL;
+ return ret;
+ }
if (strlen (POST_DATA) != *upload_data_size)
return MHD_YES;
*upload_data_size = 0;
@@ -116,60 +126,85 @@
CURLcode errornum;
int i;
char url[1024];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1350;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
for (i = 0; i < LOOPCOUNT; i++)
+ {
+ if (99 == i % 100)
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ cbc.pos = 0;
+ buf[0] = '\0';
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hw%d",
+ port,
+ i);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- if (99 == i % 100)
- fprintf (stderr, ".");
- c = curl_easy_init ();
- cbc.pos = 0;
- buf[0] = '\0';
- sprintf (url, "http://127.0.0.1:1080/hw%d", i);
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
- if ((buf[0] != 'O') || (buf[1] != 'K'))
- {
- MHD_stop_daemon (d);
- return 4;
- }
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ curl_easy_cleanup (c);
+ if ((buf[0] != 'O') || (buf[1] != 'K'))
+ {
+ MHD_stop_daemon (d);
+ return 4;
}
+ }
MHD_stop_daemon (d);
if (LOOPCOUNT >= 99)
fprintf (stderr, "\n");
return 0;
}
+
static int
testMultithreadedPost ()
{
@@ -180,60 +215,88 @@
CURLcode errornum;
int i;
char url[1024];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1351;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL,
+ &ahc_echo, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
for (i = 0; i < LOOPCOUNT; i++)
+ {
+ if (99 == i % 100)
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ cbc.pos = 0;
+ buf[0] = '\0';
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hw%d",
+ port,
+ i);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- if (99 == i % 100)
- fprintf (stderr, ".");
- c = curl_easy_init ();
- cbc.pos = 0;
- buf[0] = '\0';
- sprintf (url, "http://127.0.0.1:1081/hw%d", i);
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
- if ((buf[0] != 'O') || (buf[1] != 'K'))
- {
- MHD_stop_daemon (d);
- return 64;
- }
+ MHD_stop_daemon (d);
+ return 32;
+ }
+ curl_easy_cleanup (c);
+ if ((buf[0] != 'O') || (buf[1] != 'K'))
+ {
+ MHD_stop_daemon (d);
+ return 64;
}
+ }
MHD_stop_daemon (d);
if (LOOPCOUNT >= 99)
fprintf (stderr, "\n");
return 0;
}
+
static int
testMultithreadedPoolPost ()
{
@@ -244,61 +307,87 @@
CURLcode errornum;
int i;
char url[1024];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1352;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
for (i = 0; i < LOOPCOUNT; i++)
+ {
+ if (99 == i % 100)
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ cbc.pos = 0;
+ buf[0] = '\0';
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hw%d",
+ port,
+ i);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
- if (99 == i % 100)
- fprintf (stderr, ".");
- c = curl_easy_init ();
- cbc.pos = 0;
- buf[0] = '\0';
- sprintf (url, "http://127.0.0.1:1081/hw%d", i);
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
curl_easy_cleanup (c);
- if ((buf[0] != 'O') || (buf[1] != 'K'))
- {
- MHD_stop_daemon (d);
- return 64;
- }
+ MHD_stop_daemon (d);
+ return 32;
}
+ curl_easy_cleanup (c);
+ if ((buf[0] != 'O') || (buf[1] != 'K'))
+ {
+ MHD_stop_daemon (d);
+ return 64;
+ }
+ }
MHD_stop_daemon (d);
if (LOOPCOUNT >= 99)
fprintf (stderr, "\n");
return 0;
}
+
static int
testExternalPost ()
{
@@ -325,132 +414,158 @@
unsigned long long timeout;
long ctimeout;
char url[1024];
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1353;
+ if (oneone)
+ port += 10;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ for (i = 0; i < LOOPCOUNT; i++)
+ {
+ if (99 == i % 100)
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ cbc.pos = 0;
+ buf[0] = '\0';
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hw%d",
+ port,
+ i);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
{
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 1024;
}
- for (i = 0; i < LOOPCOUNT; i++)
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
{
- if (99 == i % 100)
- fprintf (stderr, ".");
- c = curl_easy_init ();
- cbc.pos = 0;
- buf[0] = '\0';
- sprintf (url, "http://127.0.0.1:1082/hw%d", i);
- curl_easy_setopt (c, CURLOPT_URL, url);
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- mret = curl_multi_add_handle (multi, c);
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ while (CURLM_CALL_MULTI_PERFORM ==
+ curl_multi_perform (multi, &running))
+ ;
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ if (MHD_NO == MHD_get_timeout (d, &timeout))
+ timeout = 100; /* 100ms == INFTY -- CURL bug... */
+ if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) &&
+ (ctimeout < (long long) timeout) && (ctimeout >= 0))
+ timeout = ctimeout;
+ if ( (c == NULL) || (running == 0) )
+ timeout = 0; /* terminate quickly... */
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+ if (EINTR == errno)
+ continue;
+ fprintf (stderr,
+ "select failed: %s\n",
+ strerror (errno));
+ break;
+ }
+ while (CURLM_CALL_MULTI_PERFORM ==
+ curl_multi_perform (multi, &running))
+ ;
+ if (running == 0)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
{
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- while (CURLM_CALL_MULTI_PERFORM ==
- curl_multi_perform (multi, &running));
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- if (MHD_NO == MHD_get_timeout (d, &timeout))
- timeout = 100; /* 100ms == INFTY -- CURL bug... */
- if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) &&
- (ctimeout < timeout) && (ctimeout >= 0))
- timeout = ctimeout;
- if ( (c == NULL) || (running == 0) )
- timeout = 0; /* terminate quickly... */
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR == errno)
- continue;
- fprintf (stderr,
- "select failed: %s\n",
- strerror (errno));
- break;
- }
- while (CURLM_CALL_MULTI_PERFORM ==
- curl_multi_perform (multi, &running));
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
curl_multi_remove_handle (multi, c);
curl_easy_cleanup (c);
+ c = NULL;
}
- if ((buf[0] != 'O') || (buf[1] != 'K'))
- {
- curl_multi_cleanup (multi);
- MHD_stop_daemon (d);
- return 8192;
- }
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ }
+ if ((buf[0] != 'O') || (buf[1] != 'K'))
+ {
+ curl_multi_cleanup (multi);
+ MHD_stop_daemon (d);
+ return 8192;
}
+ }
curl_multi_cleanup (multi);
MHD_stop_daemon (d);
if (LOOPCOUNT >= 99)
@@ -466,18 +581,18 @@
/**
- * Get the current timestamp
+ * Get the current timestamp
*
* @return current time in ms
*/
-static unsigned long long
+static unsigned long long
now ()
{
struct timeval tv;
gettimeofday (&tv, NULL);
- return (((unsigned long long) tv.tv_sec * 1000LL) +
- ((unsigned long long) tv.tv_usec / 1000LL));
+ return (((unsigned long long) tv.tv_sec * 1000LL)
+ + ((unsigned long long) tv.tv_usec / 1000LL));
}
@@ -485,51 +600,64 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- start_time = now();
- errorCount += testInternalPost ();
- fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
- "internal select",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
- GAUGER ("internal select",
- oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
- "requests/s");
- start_time = now();
- errorCount += testMultithreadedPost ();
- fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
- "multithreaded post",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
- GAUGER ("Multithreaded select",
- oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
- "requests/s");
- start_time = now();
- errorCount += testMultithreadedPoolPost ();
- fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
- "thread with pool",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
- GAUGER ("thread with pool",
- oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
- "requests/s");
- start_time = now();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ start_time = now ();
+ errorCount += testInternalPost ();
+ fprintf (stderr,
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" :
+ "%s: Sequential POSTs (http/1.0) %f/s\n",
+ "internal select",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0));
+ GAUGER ("internal select",
+ oneone ? "Sequential POSTs (http/1.1)" :
+ "Sequential POSTs (http/1.0)",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0),
+ "requests/s");
+ start_time = now ();
+ errorCount += testMultithreadedPost ();
+ fprintf (stderr,
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" :
+ "%s: Sequential POSTs (http/1.0) %f/s\n",
+ "multithreaded post",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0));
+ GAUGER ("Multithreaded select",
+ oneone ? "Sequential POSTs (http/1.1)" :
+ "Sequential POSTs (http/1.0)",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0),
+ "requests/s");
+ start_time = now ();
+ errorCount += testMultithreadedPoolPost ();
+ fprintf (stderr,
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" :
+ "%s: Sequential POSTs (http/1.0) %f/s\n",
+ "thread with pool",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0));
+ GAUGER ("thread with pool",
+ oneone ? "Sequential POSTs (http/1.1)" :
+ "Sequential POSTs (http/1.0)",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0),
+ "requests/s");
+ }
+ start_time = now ();
errorCount += testExternalPost ();
fprintf (stderr,
- oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
- "external select",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
+ oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" :
+ "%s: Sequential POSTs (http/1.0) %f/s\n",
+ "external select",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0));
GAUGER ("external select",
- oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
- (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
- "requests/s");
+ oneone ? "Sequential POSTs (http/1.1)" :
+ "Sequential POSTs (http/1.0)",
+ (double) 1000 * LOOPCOUNT / (now () - start_time + 1.0),
+ "requests/s");
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
curl_global_cleanup ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_postform.c
^
|
@@ -31,19 +31,23 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
#include <gcrypt.h>
#endif
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
#ifndef WINDOWS
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#include "mhd_has_in_name.h"
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
@@ -58,11 +62,12 @@
static void
completed_cb (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct MHD_PostProcessor *pp = *con_cls;
+ (void) cls; (void) connection; (void) toe; /* Unused. Silent compiler warning. */
if (NULL != pp)
MHD_destroy_post_processor (pp);
@@ -88,7 +93,7 @@
* in that it fails to support incremental processing.
* (to be fixed in the future)
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
enum MHD_ValueKind kind,
const char *key,
@@ -98,6 +103,8 @@
const char *value, uint64_t off, size_t size)
{
int *eok = cls;
+ (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; (void) off; /* Unused. Silent compiler warning. */
#if 0
fprintf (stderr, "PI sees %s-%.*s\n", key, size, value);
@@ -112,7 +119,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -124,38 +131,40 @@
static int eok;
struct MHD_Response *response;
struct MHD_PostProcessor *pp;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) version; /* Unused. Silent compiler warning. */
if (0 != strcmp ("POST", method))
- {
- printf ("METHOD: %s\n", method);
- return MHD_NO; /* unexpected method */
- }
+ {
+ printf ("METHOD: %s\n", method);
+ return MHD_NO; /* unexpected method */
+ }
pp = *unused;
if (pp == NULL)
- {
- eok = 0;
- pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
- if (pp == NULL)
- abort ();
- *unused = pp;
- }
+ {
+ eok = 0;
+ pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+ if (pp == NULL)
+ abort ();
+ *unused = pp;
+ }
MHD_post_process (pp, upload_data, *upload_data_size);
if ((eok == 3) && (0 == *upload_data_size))
- {
- response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- MHD_destroy_post_processor (pp);
- *unused = NULL;
- return ret;
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ MHD_destroy_post_processor (pp);
+ *unused = NULL;
+ return ret;
+ }
*upload_data_size = 0;
return MHD_YES;
}
+
static struct curl_httppost *
make_form ()
{
@@ -179,43 +188,64 @@
struct CBC cbc;
CURLcode errornum;
struct curl_httppost *pd;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1390;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
pd = make_form ();
curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- curl_formfree (pd);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
curl_formfree (pd);
MHD_stop_daemon (d);
@@ -226,6 +256,7 @@
return 0;
}
+
static int
testMultithreadedPost ()
{
@@ -235,43 +266,65 @@
struct CBC cbc;
CURLcode errornum;
struct curl_httppost *pd;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1390;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
pd = make_form ();
curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- curl_formfree (pd);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
curl_formfree (pd);
MHD_stop_daemon (d);
@@ -282,6 +335,7 @@
return 0;
}
+
static int
testMultithreadedPoolPost ()
{
@@ -291,44 +345,65 @@
struct CBC cbc;
CURLcode errornum;
struct curl_httppost *pd;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1391;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
pd = make_form ();
curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- curl_formfree (pd);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
curl_formfree (pd);
MHD_stop_daemon (d);
@@ -339,6 +414,7 @@
return 0;
}
+
static int
testExternalPost ()
{
@@ -362,117 +438,147 @@
time_t start;
struct timeval tv;
struct curl_httppost *pd;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1392;
+ if (oneone)
+ port += 10;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
pd = make_form ();
curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_formfree (pd);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
- curl_formfree (pd);
MHD_stop_daemon (d);
- return 512;
+ curl_formfree (pd);
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
- curl_formfree (pd);
curl_easy_cleanup (c);
+ curl_formfree (pd);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- curl_formfree (pd);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- curl_formfree (pd);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__,
- curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__,
+ curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
curl_formfree (pd);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -487,20 +593,27 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
+#ifdef MHD_HTTPS_REQUIRE_GRYPT
#ifdef HAVE_GCRYPT_H
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+#endif /* MHD_HTTPS_REQUIRE_GRYPT */
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPost ();
- errorCount += testMultithreadedPost ();
- errorCount += testMultithreadedPoolPost ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPost ();
+ errorCount += testMultithreadedPost ();
+ errorCount += testMultithreadedPoolPost ();
+ }
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_process_arguments.c
^
|
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
@@ -59,7 +60,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -71,16 +72,17 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
const char *hdr;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
hdr = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "k");
if ((hdr == NULL) || (0 != strcmp (hdr, "v x")))
@@ -94,12 +96,12 @@
if ((hdr == NULL) || (0 != strcmp (hdr, "\240bar")))
abort ();
if (3 != MHD_get_connection_values (connection,
- MHD_GET_ARGUMENT_KIND,
- NULL, NULL))
+ MHD_GET_ARGUMENT_KIND,
+ NULL, NULL))
abort ();
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -130,21 +132,42 @@
struct CURLMsg *msg;
time_t start;
struct timeval tv;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1410;
+ if (oneone)
+ port += 5;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
curl_easy_setopt (c, CURLOPT_URL,
- "http://127.0.0.1:21080/hello+world?k=v+x&hash=%23foo&space=%A0bar");
+ "http://127.0.0.1/hello+world?k=v+x&hash=%23foo&space=%A0bar");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
@@ -154,85 +177,94 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system! */
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello+world"))
return 8192;
@@ -246,9 +278,11 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += testExternalGet ();
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_put.c
^
|
@@ -31,16 +31,17 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
static int oneone;
@@ -66,6 +67,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -78,7 +80,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -89,28 +92,29 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
if (0 != strcasecmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ if (*upload_data_size != 8)
+ return MHD_YES; /* not yet ready */
+ if (0 == memcmp (upload_data, "Hello123", 8))
{
- if (*upload_data_size != 8)
- return MHD_YES; /* not yet ready */
- if (0 == memcmp (upload_data, "Hello123", 8))
- {
- *upload_data_size = 0;
- }
- else
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
- *done = 1;
- return MHD_YES;
+ *upload_data_size = 0;
}
+ else
+ {
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+ *done = 1;
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url), (void*) url,
- MHD_RESPMEM_MUST_COPY);
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -127,43 +131,64 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1450;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -173,6 +198,7 @@
return 0;
}
+
static int
testMultithreadedPut ()
{
@@ -183,43 +209,65 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1451;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -230,6 +278,7 @@
return 0;
}
+
static int
testMultithreadedPoolPut ()
{
@@ -240,44 +289,66 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1452;
+ if (oneone)
+ port += 10;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1081,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -302,124 +373,154 @@
fd_set ws;
fd_set es;
MHD_socket maxsock;
-#ifdef MHD_WINSOCK_SOCKETS
int maxposixs; /* Max socket number unused on W32 */
-#else /* MHD_POSIX_SOCKETS */
-#define maxposixs maxsock
-#endif /* MHD_POSIX_SOCKETS */
int running;
struct CURLMsg *msg;
time_t start;
struct timeval tv;
unsigned int pos = 0;
int done_flag = 0;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1453;
+ if (oneone)
+ port += 10;
+ }
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+#ifdef MHD_POSIX_SOCKETS
+ if (maxsock > maxposixs)
+ maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__, curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ _exit (99);
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__, curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -429,19 +530,23 @@
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPut ();
- errorCount += testMultithreadedPut ();
- errorCount += testMultithreadedPoolPut ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
+ }
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_put_chunked.c
^
|
@@ -37,11 +37,11 @@
#include <unistd.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
struct CBC
@@ -67,6 +67,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -79,7 +80,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -90,37 +92,40 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int have;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) < 8)
+ {
+ have = *upload_data_size;
+ if (have + *done > 8)
{
- have = *upload_data_size;
- if (have + *done > 8)
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
- if (0 == memcmp (upload_data, &"Hello123"[*done], have))
- {
- *done += have;
- *upload_data_size = 0;
- }
- else
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
-#if 0
- fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
-#endif
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+ if (0 == have)
return MHD_YES;
+ if (0 == memcmp (upload_data, &"Hello123"[*done], have))
+ {
+ *done += have;
+ *upload_data_size = 0;
}
+ else
+ {
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+#if 0
+ fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
+#endif
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -137,43 +142,60 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1440;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 11080,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
/*
- // by not giving the file size, we force chunking!
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
*/
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -183,6 +205,7 @@
return 0;
}
+
static int
testMultithreadedPut ()
{
@@ -193,43 +216,61 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1441;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 11081,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
/*
- // by not giving the file size, we force chunking!
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
*/
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -240,6 +281,7 @@
return 0;
}
+
static int
testMultithreadedPoolPut ()
{
@@ -250,44 +292,62 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1442;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 11081,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
- MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+ MHD_OPTION_THREAD_POOL_SIZE, MHD_CPU_COUNT,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
/*
- // by not giving the file size, we force chunking!
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
*/
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -323,114 +383,140 @@
struct timeval tv;
unsigned int pos = 0;
int done_flag = 0;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1443;
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 11082,
+ port,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 256;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11082/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
/*
- // by not giving the file size, we force chunking!
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
*/
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (multi != NULL))
+ {
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
{
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 512;
+ return 2048;
}
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
{
+ curl_multi_remove_handle (multi, c);
curl_multi_cleanup (multi);
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- return 1024;
+ return 4096;
}
- start = time (NULL);
- while ((time (NULL) - start < 5) && (multi != NULL))
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
{
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- msg = curl_multi_info_read (multi, &running);
- if (msg == NULL)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__,
- curl_easy_strerror (msg->data.result));
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
- if (multi != NULL)
+ curl_multi_perform (multi, &running);
+ if (running == 0)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ msg = curl_multi_info_read (multi, &running);
+ if (msg == NULL)
+ break;
+ if (msg->msg == CURLMSG_DONE)
+ {
+ if (msg->data.result != CURLE_OK)
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__,
+ curl_easy_strerror (msg->data.result));
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
+ }
}
+ MHD_run (d);
+ }
+ if (multi != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
return 8192;
@@ -440,17 +526,20 @@
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPut ();
- errorCount += testMultithreadedPut ();
- errorCount += testMultithreadedPoolPut ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ errorCount += testMultithreadedPoolPut ();
+ }
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_quiesce.c
^
|
@@ -40,11 +40,11 @@
#include <sys/socket.h>
#endif
-#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
-#undef CPU_COUNT
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
#endif
-#if !defined(CPU_COUNT)
-#define CPU_COUNT 2
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
#endif
@@ -55,6 +55,7 @@
size_t size;
};
+static int port;
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
@@ -69,7 +70,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -81,19 +82,20 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -104,15 +106,16 @@
static void
request_completed (void *cls, struct MHD_Connection *connection,
- void **con_cls, enum MHD_RequestTerminationCode code)
+ void **con_cls, enum MHD_RequestTerminationCode code)
{
- int *done = (int *)cls;
+ int *done = (int *) cls;
+ (void) connection; (void) con_cls; (void) code; /* Unused. Silent compiler warning. */
*done = 1;
}
static void *
-ServeOneRequest(void *param)
+ServeOneRequest (void *param)
{
struct MHD_Daemon *d;
fd_set rs;
@@ -126,7 +129,7 @@
fd = (MHD_socket) (intptr_t) param;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 1082, NULL, NULL, &ahc_echo, "GET",
+ 0, NULL, NULL, &ahc_echo, "GET",
MHD_OPTION_LISTEN_SOCKET, fd,
MHD_OPTION_NOTIFY_COMPLETED, &request_completed, &done,
MHD_OPTION_END);
@@ -135,32 +138,41 @@
start = time (NULL);
while ((time (NULL) - start < 5) && done == 0)
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- MHD_stop_daemon (d);
- MHD_socket_close_chk_(fd);
- return "MHD_get_fdset() failed";
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- MHD_run (d);
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ MHD_stop_daemon (d);
+ MHD_socket_close_chk_ (fd);
+ return "MHD_get_fdset() failed";
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
}
+ MHD_run (d);
+ }
fd = MHD_quiesce_daemon (d);
if (MHD_INVALID_SOCKET == fd)
- {
- MHD_stop_daemon (d);
- return "MHD_quiesce_daemon() failed in ServeOneRequest()";
- }
+ {
+ MHD_stop_daemon (d);
+ return "MHD_quiesce_daemon() failed in ServeOneRequest()";
+ }
MHD_stop_daemon (d);
return done ? NULL : "Requests was not served by ServeOneRequest()";
}
@@ -172,17 +184,18 @@
CURL *c;
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
return c;
}
@@ -200,39 +213,60 @@
pthread_t thrd;
const char *thrdRet;
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1480;
+
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- if (pool_count > 0) {
+ if (pool_count > 0)
+ {
d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
- 11080, NULL, NULL, &ahc_echo, "GET",
- MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET",
+ MHD_OPTION_THREAD_POOL_SIZE, pool_count,
+ MHD_OPTION_END);
- } else {
+ }
+ else
+ {
d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
}
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
- c = setupCURL(&cbc);
+ c = setupCURL (&cbc);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
- if (cbc.pos != strlen ("/hello_world")) {
+ if (cbc.pos != strlen ("/hello_world"))
+ {
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return 4;
}
- if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) {
+ if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+ {
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return 8;
@@ -240,78 +274,79 @@
fd = MHD_quiesce_daemon (d);
if (MHD_INVALID_SOCKET == fd)
- {
- fprintf (stderr,
- "MHD_quiesce_daemon failed.\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
- if (0 != pthread_create(&thrd, NULL, &ServeOneRequest, (void*)(intptr_t) fd))
- {
- fprintf (stderr, "pthread_create failed\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
- }
+ {
+ fprintf (stderr,
+ "MHD_quiesce_daemon failed.\n");
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ if (0 != pthread_create (&thrd, NULL, &ServeOneRequest,
+ (void*) (intptr_t) fd))
+ {
+ fprintf (stderr, "pthread_create failed\n");
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 16;
+ }
cbc.pos = 0;
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
- if (0 != pthread_join(thrd, (void**)&thrdRet))
- {
- fprintf (stderr, "pthread_join failed\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
- }
+ if (0 != pthread_join (thrd, (void**) &thrdRet))
+ {
+ fprintf (stderr, "pthread_join failed\n");
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 16;
+ }
if (NULL != thrdRet)
- {
- fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 16;
- }
+ {
+ fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 16;
+ }
if (cbc.pos != strlen ("/hello_world"))
- {
- fprintf(stderr, "%s\n", cbc.buf);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_(fd);
- return 4;
- }
+ {
+ fprintf (stderr, "%s\n", cbc.buf);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ MHD_socket_close_chk_ (fd);
+ return 4;
+ }
if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
- {
- fprintf(stderr, "%s\n", cbc.buf);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_(fd);
- return 8;
- }
+ {
+ fprintf (stderr, "%s\n", cbc.buf);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ MHD_socket_close_chk_ (fd);
+ return 8;
+ }
/* at this point, the forked server quit, and the new
* server has quiesced, so new requests should fail
*/
if (CURLE_OK == (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr, "curl_easy_perform should fail\n");
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- MHD_socket_close_chk_(fd);
- return 2;
- }
+ {
+ fprintf (stderr, "curl_easy_perform should fail\n");
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ MHD_socket_close_chk_ (fd);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
- MHD_socket_close_chk_(fd);
+ MHD_socket_close_chk_ (fd);
return 0;
}
@@ -342,134 +377,158 @@
int i;
MHD_socket fd;
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1481;
+
multi = NULL;
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_ERROR_LOG,
- 11080,
+ port,
NULL, NULL,
&ahc_echo, "GET",
MHD_OPTION_END);
if (d == NULL)
return 256;
- c = setupCURL(&cbc);
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
+ c = setupCURL (&cbc);
multi = curl_multi_init ();
if (multi == NULL)
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 512;
+ }
mret = curl_multi_add_handle (multi, c);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 1024;
- }
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 1024;
+ }
for (i = 0; i < 2; i++)
+ {
+ start = time (NULL);
+ while ( (time (NULL) - start < 5) &&
+ (NULL != multi) )
{
- start = time (NULL);
- while ( (time (NULL) - start < 5) &&
- (NULL != multi) )
- {
- maxsock = MHD_INVALID_SOCKET;
- maxposixs = -1;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
- {
- if (EINTR != errno)
- abort ();
- }
- curl_multi_perform (multi, &running);
- if (0 == running)
- {
- msg = curl_multi_info_read (multi, &running);
- if (NULL == msg)
- break;
- if (msg->msg == CURLMSG_DONE)
- {
- if (i == 0 && msg->data.result != CURLE_OK)
- printf ("%s failed at %s:%d: `%s'\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__,
- curl_easy_strerror (msg->data.result));
- else if ( (i == 1) &&
- (msg->data.result == CURLE_OK) )
- printf ("%s should have failed at %s:%d\n",
- "curl_multi_perform",
- __FILE__,
- __LINE__);
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- c = NULL;
- multi = NULL;
- }
- }
- MHD_run (d);
- }
-
- if (0 == i)
+ maxsock = MHD_INVALID_SOCKET;
+ maxposixs = -1;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
+ {
+#ifdef MHD_POSIX_SOCKETS
+ if (EINTR != errno)
+ abort ();
+#else
+ if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
+ ws.
+ fd_count)
+ || (0 != es.fd_count) )
+ abort ();
+ Sleep (1000);
+#endif
+ }
+ curl_multi_perform (multi, &running);
+ if (0 == running)
+ {
+ msg = curl_multi_info_read (multi, &running);
+ if (NULL == msg)
+ break;
+ if (msg->msg == CURLMSG_DONE)
{
- /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
- fd = MHD_quiesce_daemon(d);
- if (MHD_INVALID_SOCKET == fd)
- {
- fprintf (stderr,
- "MHD_quiesce_daemon failed.\n");
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
- c = setupCURL (&cbc);
- multi = curl_multi_init ();
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32768;
- }
+ if ((i == 0) && (msg->data.result != CURLE_OK) )
+ printf ("%s failed at %s:%d: `%s'\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__,
+ curl_easy_strerror (msg->data.result));
+ else if ( (i == 1) &&
+ (msg->data.result == CURLE_OK) )
+ printf ("%s should have failed at %s:%d\n",
+ "curl_multi_perform",
+ __FILE__,
+ __LINE__);
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ c = NULL;
+ multi = NULL;
}
+ }
+ MHD_run (d);
}
- if (NULL != multi)
+
+ if (0 == i)
{
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- curl_multi_cleanup (multi);
+ /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
+ fd = MHD_quiesce_daemon (d);
+ if (MHD_INVALID_SOCKET == fd)
+ {
+ fprintf (stderr,
+ "MHD_quiesce_daemon failed.\n");
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
+ c = setupCURL (&cbc);
+ multi = curl_multi_init ();
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32768;
+ }
}
+ }
+ if (NULL != multi)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ curl_multi_cleanup (multi);
+ }
MHD_stop_daemon (d);
MHD_socket_close_chk_ (fd);
if (cbc.pos != strlen ("/hello_world"))
@@ -484,26 +543,37 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
- errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
- errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, 0);
errorCount += testExternalGet ();
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
- {
- errorCount += testGet(MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL);
- errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL);
- errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_POLL);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
+ errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
+ errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, MHD_CPU_COUNT, 0);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL);
+ errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD, 0,
+ MHD_USE_POLL);
+ errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, MHD_CPU_COUNT,
+ MHD_USE_POLL);
}
- if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
{
errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_EPOLL);
- errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_EPOLL);
+ errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, MHD_CPU_COUNT,
+ MHD_USE_EPOLL);
}
- if (errorCount != 0)
- fprintf (stderr, "Error (code: %u)\n", errorCount);
+ }
+ if (0 != errorCount)
+ fprintf (stderr,
+ "Error (code: %u)\n",
+ errorCount);
curl_global_cleanup ();
return errorCount != 0; /* 0 == pass */
}
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_quiesce_stream.c
^
|
@@ -22,6 +22,7 @@
* @brief Testcase for libmicrohttpd quiescing
* @author Markus Doppelbauer
* @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
*/
#include "mhd_options.h"
#include <stdlib.h>
@@ -34,7 +35,7 @@
#include <unistd.h>
#elif defined(_WIN32)
#include <windows.h>
-#define sleep(s) (Sleep((s)*1000), 0)
+#define sleep(s) (Sleep ((s) * 1000), 0)
#endif /* _WIN32 */
@@ -47,7 +48,8 @@
unsigned int line,
const char *reason)
{
- fprintf( stderr,
+ (void) cls; /* Unused. Silent compiler warning. */
+ fprintf (stderr,
"PANIC: exit process: %s at %s:%u\n",
reason,
file,
@@ -71,19 +73,20 @@
suspend_connection (struct MHD_Connection *connection)
{
pthread_t thread_id;
+ int status;
/* fprintf (stderr, "Calling suspend\n"); */
MHD_suspend_connection (connection);
- int status = pthread_create (&thread_id,
- NULL,
- &resume_connection,
- connection);
+ status = pthread_create (&thread_id,
+ NULL,
+ &resume_connection,
+ connection);
if (0 != status)
- {
- fprintf (stderr,
- "Could not create thead\n");
- exit( EXIT_FAILURE );
- }
+ {
+ fprintf (stderr,
+ "Could not create thead\n");
+ exit (EXIT_FAILURE);
+ }
pthread_detach (thread_id);
}
@@ -101,16 +104,18 @@
char *buf,
size_t max)
{
- static const char alphabet[] = "\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ static const char alphabet[] =
+ "\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
struct ContentReaderUserdata *userdata = cls;
+ (void) pos; (void) max; /* Unused. Silent compiler warning. */
- if( userdata->bytes_written >= 1024)
- {
- fprintf( stderr,
- "finish: %d\n",
- request_counter);
- return MHD_CONTENT_READER_END_OF_STREAM;
- }
+ if (userdata->bytes_written >= 1024)
+ {
+ fprintf (stderr,
+ "finish: %d\n",
+ request_counter);
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ }
userdata->bytes_written++;
buf[0] = alphabet[userdata->bytes_written % (sizeof(alphabet) - 1)];
suspend_connection (userdata->connection);
@@ -119,7 +124,16 @@
}
-static int
+static void
+free_crc_data (void *crc_data)
+{
+ struct ContentReaderUserdata *userdata = crc_data;
+
+ free (userdata);
+}
+
+
+static enum MHD_Result
http_AccessHandlerCallback (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -127,18 +141,23 @@
const char *version,
const char *upload_data,
size_t *upload_data_size,
- void **con_cls )
+ void **con_cls)
{
- int ret;
+ enum MHD_Result ret;
+ struct MHD_Response *response;
+ (void) cls; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
/* Never respond on first call */
if (NULL == *con_cls)
{
+ struct ContentReaderUserdata *userdata;
fprintf (stderr,
"start: %d\n",
- ++request_counter);
+ ++request_counter);
- struct ContentReaderUserdata *userdata = malloc (sizeof(struct ContentReaderUserdata));
+ userdata = malloc (sizeof(struct ContentReaderUserdata));
if (NULL == userdata)
return MHD_NO;
@@ -149,12 +168,12 @@
}
/* Second call: create response */
- struct MHD_Response *response
+ response
= MHD_create_response_from_callback (-1,
32 * 1024,
&http_ContentReaderCallback,
*con_cls,
- NULL);
+ &free_crc_data);
ret = MHD_queue_response (connection,
MHD_HTTP_OK,
response);
@@ -166,44 +185,68 @@
int
-main()
+main (void)
{
+ int port;
+ char command_line[1024];
+ /* Flags */
+ unsigned int daemon_flags
+ = MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_AUTO
+ | MHD_ALLOW_SUSPEND_RESUME
+ | MHD_USE_ITC;
+ struct MHD_Daemon *daemon;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1470;
+
/* Panic callback */
MHD_set_panic_func (&http_PanicCallback,
NULL);
- /* Flags */
- unsigned int daemon_flags
- = MHD_USE_INTERNAL_POLLING_THREAD
- | MHD_USE_AUTO
- | MHD_ALLOW_SUSPEND_RESUME
- | MHD_USE_ITC;
/* Create daemon */
- struct MHD_Daemon *daemon = MHD_start_daemon (daemon_flags,
- 8000,
- NULL,
- NULL,
- &http_AccessHandlerCallback,
- NULL,
- MHD_OPTION_END);
+ daemon = MHD_start_daemon (daemon_flags,
+ port,
+ NULL,
+ NULL,
+ &http_AccessHandlerCallback,
+ NULL,
+ MHD_OPTION_END);
if (NULL == daemon)
return 1;
- if (0 != system ("curl -s http://127.0.0.1:8000"))
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- MHD_stop_daemon (daemon);
- return 1;
+ MHD_stop_daemon (daemon); return 32;
}
+ port = (int) dinfo->port;
+ }
+ snprintf (command_line,
+ sizeof (command_line),
+ "curl -s http://127.0.0.1:%d",
+ port);
+
+ if (0 != system (command_line))
+ {
+ MHD_stop_daemon (daemon);
+ return 1;
+ }
/* wait for a request */
while (0 == request_counter)
- sleep (1);
+ (void) sleep (1);
fprintf (stderr,
"quiesce\n");
MHD_quiesce_daemon (daemon);
/* wait a second */
- sleep (1);
+ (void) sleep (1);
fprintf (stderr,
"stopping daemon\n");
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_termination.c
^
|
@@ -23,7 +23,6 @@
* @brief Testcase for libmicrohttpd tolerating client not closing immediately
* @author hollosig
*/
-#define PORT 12345
#include "platform.h"
#include <stdio.h>
@@ -48,75 +47,107 @@
#include <windows.h>
#endif
-static int
+static enum MHD_Result
connection_handler (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
- const char *upload_data, size_t * upload_data_size,
+ const char *upload_data, size_t *upload_data_size,
void **ptr)
{
static int i;
+ struct MHD_Response *response;
+ enum MHD_Result ret;
+ (void) cls; (void) url; /* Unused. Silent compiler warning. */
+ (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
if (*ptr == NULL)
- {
- *ptr = &i;
- return MHD_YES;
- }
+ {
+ *ptr = &i;
+ return MHD_YES;
+ }
if (*upload_data_size != 0)
- {
- (*upload_data_size) = 0;
- return MHD_YES;
- }
+ {
+ (*upload_data_size) = 0;
+ return MHD_YES;
+ }
- struct MHD_Response *response =
+ response =
MHD_create_response_from_buffer (strlen ("Response"), "Response",
- MHD_RESPMEM_PERSISTENT);
- int ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
+
static size_t
write_data (void *ptr, size_t size, size_t nmemb, void *stream)
{
+ (void) ptr; (void) stream; /* Unused. Silent compiler warning. */
return size * nmemb;
}
+
int
-main ()
+main (void)
{
struct MHD_Daemon *daemon;
+ int port;
+ char url[255];
+ CURL *curl;
+ CURLcode success;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ port = 1490;
+
- daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- PORT,
+ daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD
+ | MHD_USE_ERROR_LOG,
+ port,
NULL,
NULL, connection_handler, NULL, MHD_OPTION_END);
if (daemon == NULL)
+ {
+ fprintf (stderr, "Daemon cannot be started!");
+ exit (1);
+ }
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
{
- fprintf (stderr, "Daemon cannot be started!");
- exit (1);
+ MHD_stop_daemon (daemon); return 32;
}
+ port = (int) dinfo->port;
+ }
- CURL *curl = curl_easy_init ();
- //curl_easy_setopt(curl, CURLOPT_POST, 1L);
- char url[255];
- sprintf (url, "http://127.0.0.1:%d", PORT);
+ curl = curl_easy_init ();
+ /* curl_easy_setopt(curl, CURLOPT_POST, 1L); */
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d",
+ port);
curl_easy_setopt (curl, CURLOPT_URL, url);
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
- CURLcode success = curl_easy_perform (curl);
+ success = curl_easy_perform (curl);
if (success != 0)
- {
- fprintf (stderr, "CURL Error");
- exit (1);
- }
+ {
+ fprintf (stderr, "CURL Error");
+ exit (1);
+ }
/* CPU used to go crazy here */
- sleep (1);
+ (void) sleep (1);
curl_easy_cleanup (curl);
MHD_stop_daemon (daemon);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_timeout.c
^
|
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifndef WINDOWS
#include <unistd.h>
@@ -50,36 +51,37 @@
};
-static void
-termination_cb (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+static void
+termination_cb (void *cls,
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
int *test = cls;
+ (void) connection; (void) con_cls; /* Unused. Silent compiler warning. */
switch (toe)
+ {
+ case MHD_REQUEST_TERMINATED_COMPLETED_OK:
+ if (test == &withoutTimeout)
{
- case MHD_REQUEST_TERMINATED_COMPLETED_OK :
- if (test == &withoutTimeout)
- {
- withoutTimeout = 0;
- }
- break;
- case MHD_REQUEST_TERMINATED_WITH_ERROR :
- case MHD_REQUEST_TERMINATED_READ_ERROR :
- break;
- case MHD_REQUEST_TERMINATED_TIMEOUT_REACHED :
- if (test == &withTimeout)
- {
- withTimeout = 0;
- }
- break;
- case MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN:
- break;
- case MHD_REQUEST_TERMINATED_CLIENT_ABORT:
- break;
+ withoutTimeout = 0;
}
+ break;
+ case MHD_REQUEST_TERMINATED_WITH_ERROR:
+ case MHD_REQUEST_TERMINATED_READ_ERROR:
+ break;
+ case MHD_REQUEST_TERMINATED_TIMEOUT_REACHED:
+ if (test == &withTimeout)
+ {
+ withTimeout = 0;
+ }
+ break;
+ case MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN:
+ break;
+ case MHD_REQUEST_TERMINATED_CLIENT_ABORT:
+ break;
+ }
}
@@ -91,7 +93,7 @@
wrt = size * nmemb;
if (wrt > 8 - (*pos))
- wrt = 8 - (*pos);
+ wrt = 8 - (*pos);
memcpy (stream, &("Hello123"[*pos]), wrt);
(*pos) += wrt;
return wrt;
@@ -101,6 +103,7 @@
static size_t
putBuffer_fail (void *stream, size_t size, size_t nmemb, void *ptr)
{
+ (void) stream; (void) size; (void) nmemb; (void) ptr; /* Unused. Silent compiler warning. */
return 0;
}
@@ -118,7 +121,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -129,29 +132,30 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ if (*upload_data_size != 8)
+ return MHD_YES; /* not yet ready */
+ if (0 == memcmp (upload_data, "Hello123", 8))
+ {
+ *upload_data_size = 0;
+ }
+ else
{
- if (*upload_data_size != 8)
- return MHD_YES; /* not yet ready */
- if (0 == memcmp (upload_data, "Hello123", 8))
- {
- *upload_data_size = 0;
- }
- else
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
- *done = 1;
- return MHD_YES;
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
}
+ *done = 1;
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -168,43 +172,65 @@
unsigned int pos = 0;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1500;
+ if (oneone)
+ port += 5;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
MHD_OPTION_CONNECTION_TIMEOUT, 2,
- MHD_OPTION_NOTIFY_COMPLETED, &termination_cb, &withTimeout,
+ MHD_OPTION_NOTIFY_COMPLETED, &termination_cb,
+ &withTimeout,
MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -214,6 +240,7 @@
return 0;
}
+
static int
testWithTimeout ()
{
@@ -223,48 +250,70 @@
struct CBC cbc;
int done_flag = 0;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1501;
+ if (oneone)
+ port += 5;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
- 1080,
+ port,
NULL, NULL, &ahc_echo, &done_flag,
MHD_OPTION_CONNECTION_TIMEOUT, 2,
- MHD_OPTION_NOTIFY_COMPLETED, &termination_cb, &withoutTimeout,
+ MHD_OPTION_NOTIFY_COMPLETED, &termination_cb,
+ &withoutTimeout,
MHD_OPTION_END);
if (d == NULL)
return 16;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer_fail);
curl_easy_setopt (c, CURLOPT_READDATA, &testWithTimeout);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
else
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- if (errornum == CURLE_GOT_NOTHING)
- /* mhd had the timeout */
- return 0;
- else
- /* curl had the timeout first */
- return 32;
- }
+ {
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ if (errornum == CURLE_GOT_NOTHING)
+ /* mhd had the timeout */
+ return 0;
+ else
+ /* curl had the timeout first */
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return 64;
@@ -275,17 +324,19 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 16;
errorCount += testWithoutTimeout ();
errorCount += testWithTimeout ();
if (errorCount != 0)
- fprintf (stderr,
- "Error during test execution (code: %u)\n",
- errorCount);
+ fprintf (stderr,
+ "Error during test execution (code: %u)\n",
+ errorCount);
curl_global_cleanup ();
if ((withTimeout == 0) && (withoutTimeout == 0))
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testcurl/test_urlparse.c
^
|
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include "mhd_has_in_name.h"
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
@@ -67,12 +68,14 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
test_values (void *cls,
- enum MHD_ValueKind kind,
- const char *key,
- const char *value)
+ enum MHD_ValueKind kind,
+ const char *key,
+ const char *value)
{
+ (void) cls; (void) kind; /* Unused. Silent compiler warning. */
if ( (0 == strcmp (key, "a")) &&
(0 == strcmp (value, "b")) )
matches += 1;
@@ -85,7 +88,8 @@
return MHD_YES;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -97,23 +101,24 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
MHD_get_connection_values (connection,
- MHD_GET_ARGUMENT_KIND,
- &test_values,
- NULL);
+ MHD_GET_ARGUMENT_KIND,
+ &test_values,
+ NULL);
*unused = NULL;
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -130,19 +135,41 @@
char buf[2048];
struct CBC cbc;
CURLcode errornum;
+ int port;
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+ else
+ {
+ port = 1510;
+ if (oneone)
+ port += 5;
+ }
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG
+ | poll_flag,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ {
+ MHD_stop_daemon (d); return 32;
+ }
+ port = (int) dinfo->port;
+ }
c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world?a=b&c=&d");
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world?a=b&c=&d");
+ curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
if (oneone)
@@ -152,16 +179,16 @@
/* NOTE: use of CONNECTTIMEOUT without also
setting NOSIGNAL results in really weird
crashes on my system!*/
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 2;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 2;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -178,9 +205,11 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
- oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += testInternalGet (0);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/Makefile.am
^
|
@@ -8,9 +8,16 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/include \
$(LIBCURL_CPPFLAGS)
+
+if HEAVY_TESTS
+AM_CPPFLAGS += -D_MHD_HEAVY_TESTS=1
+endif
EXTRA_DIST = README socat.c
+THREAD_ONLY_TESTS = \
+ test_long_header
+
check_PROGRAMS = \
test_get \
test_get_chunked \
@@ -23,8 +30,20 @@
test_post11 \
test_post_form11 \
test_put11 \
- test_put_large11 \
- test_long_header
+ test_put_large11
+
+.NOTPARALLEL:
+
+
+if USE_POSIX_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
+endif
+if USE_W32_THREADS
+check_PROGRAMS += \
+ $(THREAD_ONLY_TESTS)
+endif
+
TESTS = $(check_PROGRAMS)
@@ -32,43 +51,43 @@
test_get.c
test_get_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_get_chunked_SOURCES = \
test_get_chunked.c
test_get_chunked_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_post_SOURCES = \
test_post.c
test_post_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_post_form_SOURCES = \
test_post_form.c
test_post_form_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_put_SOURCES = \
test_put.c
test_put_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_put_chunked_SOURCES = \
test_put_chunked.c
test_put_chunked_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_put_large_SOURCES = \
test_put_large.c
test_put_large_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
@@ -76,34 +95,34 @@
test_get.c
test_get11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_post11_SOURCES = \
test_post.c
test_post11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_post_form11_SOURCES = \
test_post_form.c
test_post_form11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_put11_SOURCES = \
test_put.c
test_put11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_put_large11_SOURCES = \
test_put_large.c
test_put_large11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
test_long_header_SOURCES = \
test_long_header.c
test_long_header_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
- @LIBCURL@
+ @LIBCURL@
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/socat.c
^
|
@@ -43,7 +43,11 @@
* long for most user's patience. So this small
* value is the default.
*/
+#ifndef _MHD_HEAVY_TESTS
#define LOOP_COUNT 10
+#else /* ! _MHD_HEAVY_TESTS */
+#define LOOP_COUNT 200
+#endif /* ! _MHD_HEAVY_TESTS */
#define CURL_TIMEOUT 50L
@@ -67,31 +71,30 @@
};
zzuf_pid = fork ();
if (zzuf_pid == -1)
- {
- fprintf (stderr, "fork failed: %s\n", strerror (errno));
- exit (1);
- }
+ {
+ fprintf (stderr, "fork failed: %s\n", strerror (errno));
+ exit (1);
+ }
if (zzuf_pid != 0)
+ {
+ (void) sleep (1); /* allow zzuf and socat to start */
+ status = 0;
+ if (0 < waitpid (zzuf_pid, &status, WNOHANG))
{
- sleep (1); /* allow zzuf and socat to start */
- status = 0;
- if (0 < waitpid (zzuf_pid, &status, WNOHANG))
- {
- if (WIFEXITED (status))
- fprintf (stderr,
- "zzuf died with status code %d!\n",
- WEXITSTATUS (status));
- if (WIFSIGNALED (status))
- fprintf (stderr,
- "zzuf died from signal %d!\n", WTERMSIG (status));
- exit (1);
- }
- return;
+ if (WIFEXITED (status))
+ fprintf (stderr,
+ "zzuf died with status code %d!\n",
+ WEXITSTATUS (status));
+ if (WIFSIGNALED (status))
+ fprintf (stderr,
+ "zzuf died from signal %d!\n", WTERMSIG (status));
+ exit (1);
}
+ return;
+ }
setpgid (0, 0);
execvp ("zzuf", args);
fprintf (stderr, "execution of `zzuf' failed: %s\n", strerror (errno));
- zzuf_pid = 0; /* fork failed */
exit (1);
}
@@ -101,13 +104,14 @@
{
int status;
if (zzuf_pid != 0)
- {
- if (0 != killpg (zzuf_pid, SIGINT))
- fprintf (stderr, "Failed to killpg: %s\n", strerror (errno));
- kill (zzuf_pid, SIGINT);
- waitpid (zzuf_pid, &status, 0);
- sleep (1); /* allow socat to also die in peace */
- }
+ {
+ if (0 != killpg (zzuf_pid, SIGINT))
+ fprintf (stderr, "Failed to killpg: %s\n", strerror (errno));
+ kill (zzuf_pid, SIGINT);
+ waitpid (zzuf_pid, &status, 0);
+ (void) sleep (1); /* allow socat to also die in peace */
+ }
}
+
/* end of socat.c */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_get.c
^
|
@@ -59,7 +59,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -71,19 +72,30 @@
static int ptr;
const char *me = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&ptr != *unused)
- {
- *unused = &ptr;
- return MHD_YES;
- }
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
*unused = NULL;
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
if (ret == MHD_NO)
@@ -104,38 +116,40 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedGet ()
{
@@ -148,32 +162,33 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -203,90 +218,90 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ zzuf_socat_start ();
+ for (i = 0; i < LOOP_COUNT; i++)
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
{
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
MHD_stop_daemon (d);
- return 512;
+ return 1024;
}
- zzuf_socat_start ();
- for (i = 0; i < LOOP_COUNT; i++)
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
{
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- mret = curl_multi_add_handle (multi, c);
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
}
+ }
fprintf (stderr, "\n");
curl_multi_cleanup (multi);
zzuf_socat_stop ();
@@ -299,13 +314,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalGet ();
- errorCount += testMultithreadedGet ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet ();
+ errorCount += testMultithreadedGet ();
+ }
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_get_chunked.c
^
|
@@ -57,6 +57,7 @@
return size * nmemb;
}
+
/**
* MHD content reader callback that returns
* data in chunks.
@@ -67,16 +68,17 @@
struct MHD_Response **responseptr = cls;
if (pos == 128 * 10)
- {
- MHD_add_response_header (*responseptr, "Footer", "working");
- return MHD_CONTENT_READER_END_OF_STREAM;
- }
+ {
+ MHD_add_response_header (*responseptr, "Footer", "working");
+ return MHD_CONTENT_READER_END_OF_STREAM;
+ }
if (max < 128)
abort (); /* should not happen in this testcase... */
memset (buf, 'A' + (pos / 128), 128);
return 128;
}
+
/**
* Dummy function that does nothing.
*/
@@ -86,7 +88,8 @@
free (ptr);
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -98,26 +101,51 @@
const char *me = cls;
struct MHD_Response *response;
struct MHD_Response **responseptr;
- int ret;
+ enum MHD_Result ret;
+ (void) url;
+ (void) version; /* Unused. Silent compiler warning. */
+ (void) upload_data;
+ (void) upload_data_size; /* Unused. Silent compiler warning. */
+
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp (me, method))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
- {
- /* do never respond on first call */
- *ptr = &aptr;
- return MHD_YES;
- }
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
responseptr = malloc (sizeof (struct MHD_Response *));
+ if (NULL == responseptr)
+ return MHD_NO;
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
1024,
&crc, responseptr, &crcf);
+ if (NULL == response)
+ {
+ free (responseptr);
+ return MHD_NO;
+ }
*responseptr = response;
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
MHD_destroy_response (response);
return ret;
}
+
static int
testInternalGet ()
{
@@ -130,35 +158,37 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedGet ()
{
@@ -171,29 +201,30 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -223,87 +254,87 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
if (d == NULL)
return 256;
multi = curl_multi_init ();
if (multi == NULL)
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
+ zzuf_socat_start ();
+ for (i = 0; i < LOOP_COUNT; i++)
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
{
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
MHD_stop_daemon (d);
- return 512;
+ return 1024;
}
- zzuf_socat_start ();
- for (i = 0; i < LOOP_COUNT; i++)
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
{
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- mret = curl_multi_add_handle (multi, c);
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
}
+ }
fprintf (stderr, "\n");
curl_multi_cleanup (multi);
zzuf_socat_stop ();
@@ -312,16 +343,19 @@
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalGet ();
- errorCount += testMultithreadedGet ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalGet ();
+ errorCount += testMultithreadedGet ();
+ }
errorCount += testExternalGet ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_post.c
^
|
@@ -53,11 +53,12 @@
static void
completed_cb (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct MHD_PostProcessor *pp = *con_cls;
+ (void) cls; (void) connection; (void) toe; /* Unused. Silent compiler warning. */
if (NULL != pp)
MHD_destroy_post_processor (pp);
@@ -83,7 +84,7 @@
* in that it fails to support incremental processing.
* (to be fixed in the future)
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
enum MHD_ValueKind kind,
const char *key,
@@ -93,6 +94,8 @@
const char *value, uint64_t off, size_t size)
{
int *eok = cls;
+ (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; (void) off; /* Unused. Silent compiler warning. */
if ((0 == strcmp (key, "name")) &&
(size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size)))
@@ -103,7 +106,8 @@
return MHD_YES;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -115,31 +119,42 @@
static int eok;
struct MHD_Response *response;
struct MHD_PostProcessor *pp;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) version; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp ("POST", method))
- {
- return MHD_NO; /* unexpected method */
- }
+ {
+ return MHD_NO; /* unexpected method */
+ }
pp = *unused;
if (pp == NULL)
- {
- eok = 0;
- pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
- *unused = pp;
- }
+ {
+ eok = 0;
+ pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+ *unused = pp;
+ }
MHD_post_process (pp, upload_data, *upload_data_size);
if ((eok == 3) && (0 == *upload_data_size))
- {
- response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- MHD_destroy_post_processor (pp);
- *unused = NULL;
- return ret;
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ MHD_destroy_post_processor (pp);
+ *unused = NULL;
+ return ret;
+ }
*upload_data_size = 0;
return MHD_YES;
}
@@ -157,38 +172,39 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -196,6 +212,7 @@
return 0;
}
+
static int
testMultithreadedPost ()
{
@@ -208,39 +225,40 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
@@ -271,101 +289,101 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */ ,
- 1082, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
+ 1082, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 256;
multi = curl_multi_init ();
if (multi == NULL)
- {
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
- curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
- curl_easy_setopt (c, CURLOPT_POST, 1L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
+ curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
+ curl_easy_setopt (c, CURLOPT_POST, 1L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
- mret = curl_multi_add_handle (multi, c);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
-
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
}
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ }
+
+ }
fprintf (stderr, "\n");
curl_multi_cleanup (multi);
zzuf_socat_stop ();
@@ -379,13 +397,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPost ();
- errorCount += testMultithreadedPost ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPost ();
+ errorCount += testMultithreadedPost ();
+ }
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_post_form.c
^
|
@@ -51,11 +51,12 @@
static void
completed_cb (void *cls,
- struct MHD_Connection *connection,
- void **con_cls,
- enum MHD_RequestTerminationCode toe)
+ struct MHD_Connection *connection,
+ void **con_cls,
+ enum MHD_RequestTerminationCode toe)
{
struct MHD_PostProcessor *pp = *con_cls;
+ (void) cls; (void) connection; (void) toe; /* Unused. Silent compiler warning. */
if (NULL != pp)
MHD_destroy_post_processor (pp);
@@ -75,12 +76,13 @@
return size * nmemb;
}
+
/**
* Note that this post_iterator is not perfect
* in that it fails to support incremental processing.
* (to be fixed in the future)
*/
-static int
+static enum MHD_Result
post_iterator (void *cls,
enum MHD_ValueKind kind,
const char *key,
@@ -90,6 +92,8 @@
const char *value, uint64_t off, size_t size)
{
int *eok = cls;
+ (void) kind; (void) filename; (void) content_type; /* Unused. Silent compiler warning. */
+ (void) transfer_encoding; (void) off; /* Unused. Silent compiler warning. */
if (key == NULL)
return MHD_YES;
@@ -106,7 +110,7 @@
}
-static int
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -118,37 +122,49 @@
static int eok;
struct MHD_Response *response;
struct MHD_PostProcessor *pp;
- int ret;
+ enum MHD_Result ret;
+ (void) cls; (void) version; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp ("POST", method))
- {
- return MHD_NO; /* unexpected method */
- }
+ {
+ return MHD_NO; /* unexpected method */
+ }
pp = *unused;
if (pp == NULL)
- {
- eok = 0;
- pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
- if (pp == NULL)
- return MHD_NO;
- *unused = pp;
- }
+ {
+ eok = 0;
+ pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+ if (pp == NULL)
+ return MHD_NO;
+ *unused = pp;
+ }
MHD_post_process (pp, upload_data, *upload_data_size);
if ((eok == 3) && (0 == *upload_data_size))
- {
- response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- MHD_destroy_post_processor (pp);
- *unused = NULL;
- return ret;
- }
+ {
+ response = MHD_create_response_from_buffer (strlen (url),
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ MHD_destroy_post_processor (pp);
+ *unused = NULL;
+ return ret;
+ }
*upload_data_size = 0;
return MHD_YES;
}
+
static struct curl_httppost *
make_form ()
{
@@ -176,37 +192,38 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- pd = make_form ();
- curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- curl_formfree (pd);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ pd = make_form ();
+ curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -227,37 +244,38 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- pd = make_form ();
- curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- curl_formfree (pd);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ pd = make_form ();
+ curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -288,103 +306,103 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */ ,
- 1082, NULL, NULL, &ahc_echo, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
- MHD_OPTION_END);
+ d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
+ 1082, NULL, NULL, &ahc_echo, NULL,
+ MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
+ MHD_OPTION_END);
if (d == NULL)
return 256;
multi = curl_multi_init ();
if (multi == NULL)
- {
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
-
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- pd = make_form ();
- curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ pd = make_form ();
+ curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
- mret = curl_multi_add_handle (multi, c);
- if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_formfree (pd);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- curl_formfree (pd);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- curl_formfree (pd);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
curl_formfree (pd);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ curl_formfree (pd);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ curl_formfree (pd);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
}
+ curl_formfree (pd);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
+ curl_multi_cleanup (multi);
MHD_stop_daemon (d);
return 0;
@@ -395,13 +413,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPost ();
- errorCount += testMultithreadedPost ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPost ();
+ errorCount += testMultithreadedPost ();
+ }
errorCount += testExternalPost ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_put.c
^
|
@@ -62,6 +62,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -74,7 +75,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -85,29 +87,40 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ if (*upload_data_size != 8)
+ return MHD_YES; /* not yet ready */
+ if (0 == memcmp (upload_data, "Hello123", 8))
{
- if (*upload_data_size != 8)
- return MHD_YES; /* not yet ready */
- if (0 == memcmp (upload_data, "Hello123", 8))
- {
- *upload_data_size = 0;
- }
- else
- {
- printf ("Invalid upload data `%8s'!\n", upload_data);
- return MHD_NO;
- }
- *done = 1;
- return MHD_YES;
+ *upload_data_size = 0;
}
+ else
+ {
+ printf ("Invalid upload data `%8s'!\n", upload_data);
+ return MHD_NO;
+ }
+ *done = 1;
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -128,43 +141,45 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080,
- NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080,
+ NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedPut ()
{
@@ -179,37 +194,38 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
11080,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -241,99 +257,98 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_ERROR_LOG */,
11080,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 256;
multi = curl_multi_init ();
if (multi == NULL)
- {
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
-
- mret = curl_multi_add_handle (multi, c);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
}
+ }
fprintf (stderr, "\n");
curl_multi_cleanup (multi);
zzuf_socat_stop ();
@@ -346,13 +361,17 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPut ();
- errorCount += testMultithreadedPut ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ }
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_put_chunked.c
^
|
@@ -62,6 +62,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -74,7 +75,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -85,35 +87,50 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
int have;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) < 8)
+ {
+ have = *upload_data_size;
+ if (have + *done > 8)
+ {
+ return MHD_NO;
+ }
+ if (0 == have)
+ {
+ (void) 0; /* Do nothing - no data yet */
+ }
+ else if (0 == memcmp (upload_data, &"Hello123"[*done], have))
+ {
+ *done += have;
+ *upload_data_size = 0;
+ }
+ else
{
- have = *upload_data_size;
- if (have + *done > 8)
- {
- return MHD_NO;
- }
- if (0 == memcmp (upload_data, &"Hello123"[*done], have))
- {
- *done += have;
- *upload_data_size = 0;
- }
- else
- {
- return MHD_NO;
- }
+ return MHD_NO;
+ }
#if 0
- fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
+ fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
#endif
- return MHD_YES;
- }
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -141,36 +158,38 @@
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- /*
- // by not giving the file size, we force chunking!
- curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- */
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ {
+ fprintf (stderr, ".");
+ done_flag = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
+ /*
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ */
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedPut ()
{
@@ -185,7 +204,8 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
11081,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
@@ -197,27 +217,27 @@
curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
curl_easy_setopt (c, CURLOPT_READDATA, &pos);
curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
/*
- // by not giving the file size, we force chunking!
curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
*/
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
- {
- fprintf (stderr,
- "curl_easy_perform failed: `%s'\n",
- curl_easy_strerror (errornum));
- curl_easy_cleanup (c);
- MHD_stop_daemon (d);
- return 32;
- }
+ {
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ MHD_stop_daemon (d);
+ return 32;
+ }
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (cbc.pos != strlen ("/hello_world"))
@@ -261,90 +281,91 @@
multi = curl_multi_init ();
if (multi == NULL)
- {
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11082/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- /*
- // by not giving the file size, we force chunking!
- curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
- */
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ {
+ fprintf (stderr, ".");
+ done_flag = 0;
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11082/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ /* by not giving the file size, we force chunking! */
+ /*
+ curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+ */
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
- mret = curl_multi_add_handle (multi, c);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
}
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ }
+ }
fprintf (stderr, "\n");
curl_multi_cleanup (multi);
zzuf_socat_stop ();
@@ -353,16 +374,19 @@
}
-
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; (void) argv; /* Unused. Silent compiler warning. */
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
- errorCount += testInternalPut ();
- errorCount += testMultithreadedPut ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ }
errorCount += testExternalPut ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/src/testzzuf/test_put_large.c
^
|
@@ -70,6 +70,7 @@
return wrt;
}
+
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
@@ -82,7 +83,8 @@
return size * nmemb;
}
-static int
+
+static enum MHD_Result
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
@@ -93,35 +95,46 @@
{
int *done = cls;
struct MHD_Response *response;
- int ret;
+ enum MHD_Result ret;
+ (void) version; (void) unused; /* Unused. Silent compiler warning. */
+ if (NULL == url)
+ fprintf (stderr, "The \"url\" parameter is NULL.\n");
+ if (NULL == method)
+ fprintf (stderr, "The \"method\" parameter is NULL.\n");
+ if (NULL == version)
+ fprintf (stderr, "The \"version\" parameter is NULL.\n");
+ if (NULL == upload_data_size)
+ fprintf (stderr, "The \"upload_data_size\" parameter is NULL.\n");
+ if ((0 != *upload_data_size) && (NULL == upload_data))
+ fprintf (stderr, "Upload data is NULL with non-zero size.\n");
if (0 != strcmp ("PUT", method))
return MHD_NO; /* unexpected method */
if ((*done) == 0)
+ {
+ if (*upload_data_size != PUT_SIZE)
{
- if (*upload_data_size != PUT_SIZE)
- {
#if 0
- fprintf (stderr,
- "Waiting for more data (%u/%u)...\n",
- *upload_data_size, PUT_SIZE);
+ fprintf (stderr,
+ "Waiting for more data (%u/%u)...\n",
+ *upload_data_size, PUT_SIZE);
#endif
- return MHD_YES; /* not yet ready */
- }
- if (0 == memcmp (upload_data, put_buffer, PUT_SIZE))
- {
- *upload_data_size = 0;
- }
- else
- {
- return MHD_NO;
- }
- *done = 1;
- return MHD_YES;
+ return MHD_YES; /* not yet ready */
+ }
+ if (0 == memcmp (upload_data, put_buffer, PUT_SIZE))
+ {
+ *upload_data_size = 0;
+ }
+ else
+ {
+ return MHD_NO;
}
+ *done = 1;
+ return MHD_YES;
+ }
response = MHD_create_response_from_buffer (strlen (url),
- (void *) url,
- MHD_RESPMEM_MUST_COPY);
+ (void *) url,
+ MHD_RESPMEM_MUST_COPY);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
@@ -142,44 +155,46 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
- 11080,
- NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+ d = MHD_start_daemon (
+ MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
+ 11080,
+ NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 1;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
return 0;
}
+
static int
testMultithreadedPut ()
{
@@ -194,38 +209,39 @@
cbc.buf = buf;
cbc.size = 2048;
cbc.pos = 0;
- d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
+ d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+ | MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */,
11080,
NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
if (d == NULL)
return 16;
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
+ {
+ fprintf (stderr, ".");
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
- curl_easy_perform (c);
- curl_easy_cleanup (c);
- }
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_perform (c);
+ curl_easy_cleanup (c);
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
MHD_stop_daemon (d);
@@ -266,92 +282,91 @@
return 256;
multi = curl_multi_init ();
if (multi == NULL)
- {
- MHD_stop_daemon (d);
- return 512;
- }
+ {
+ MHD_stop_daemon (d);
+ return 512;
+ }
zzuf_socat_start ();
for (i = 0; i < LOOP_COUNT; i++)
- {
- fprintf (stderr, ".");
-
- c = curl_easy_init ();
- curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
- curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
- curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
- curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
- curl_easy_setopt (c, CURLOPT_READDATA, &pos);
- curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
- curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
- if (oneone)
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- else
- curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
- // NOTE: use of CONNECTTIMEOUT without also
- // setting NOSIGNAL results in really weird
- // crashes on my system!
- curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+ {
+ fprintf (stderr, ".");
+ c = curl_easy_init ();
+ curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+ curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
+ curl_easy_setopt (c, CURLOPT_READDATA, &pos);
+ curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+ curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
+ /* NOTE: use of CONNECTTIMEOUT without also
+ * setting NOSIGNAL results in really weird
+ * crashes on my system! */
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
- mret = curl_multi_add_handle (multi, c);
+ mret = curl_multi_add_handle (multi, c);
+ if (mret != CURLM_OK)
+ {
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 1024;
+ }
+ start = time (NULL);
+ while ((time (NULL) - start < 5) && (c != NULL))
+ {
+ max = 0;
+ FD_ZERO (&rs);
+ FD_ZERO (&ws);
+ FD_ZERO (&es);
+ curl_multi_perform (multi, &running);
+ mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
if (mret != CURLM_OK)
- {
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 1024;
- }
- start = time (NULL);
- while ((time (NULL) - start < 5) && (c != NULL))
- {
- max = 0;
- FD_ZERO (&rs);
- FD_ZERO (&ws);
- FD_ZERO (&es);
- curl_multi_perform (multi, &running);
- mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
- if (mret != CURLM_OK)
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 2048;
- }
- if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
- {
- curl_multi_remove_handle (multi, c);
- curl_multi_cleanup (multi);
- curl_easy_cleanup (c);
- zzuf_socat_stop ();
- MHD_stop_daemon (d);
- return 4096;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select (max + 1, &rs, &ws, &es, &tv);
- curl_multi_perform (multi, &running);
- if (running == 0)
- {
- curl_multi_info_read (multi, &running);
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- c = NULL;
- }
- MHD_run (d);
- }
- if (c != NULL)
- {
- curl_multi_remove_handle (multi, c);
- curl_easy_cleanup (c);
- }
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 2048;
+ }
+ if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_multi_cleanup (multi);
+ curl_easy_cleanup (c);
+ zzuf_socat_stop ();
+ MHD_stop_daemon (d);
+ return 4096;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000;
+ select (max + 1, &rs, &ws, &es, &tv);
+ curl_multi_perform (multi, &running);
+ if (running == 0)
+ {
+ curl_multi_info_read (multi, &running);
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
+ c = NULL;
+ }
+ MHD_run (d);
+ }
+ if (c != NULL)
+ {
+ curl_multi_remove_handle (multi, c);
+ curl_easy_cleanup (c);
}
+ }
fprintf (stderr, "\n");
zzuf_socat_stop ();
curl_multi_cleanup (multi);
@@ -364,15 +379,21 @@
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
+ (void) argc; /* Unused. Silent compiler warning. */
oneone = (NULL != strrchr (argv[0], (int) '/')) ?
- (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+ (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
put_buffer = malloc (PUT_SIZE);
+ if (0 == put_buffer)
+ return 77;
memset (put_buffer, 1, PUT_SIZE);
- errorCount += testInternalPut ();
- errorCount += testMultithreadedPut ();
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
+ {
+ errorCount += testInternalPut ();
+ errorCount += testMultithreadedPut ();
+ }
errorCount += testExternalPut ();
free (put_buffer);
if (errorCount != 0)
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/.gitignore
^
|
@@ -0,0 +1,6 @@
+/Output
+/libmicrohttpd
+/hellobrowser
+/largepost
+/simplepost
+/.vs
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/hellobrowser.vcxproj
^
|
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug-dll|Win32">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-dll|x64">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|Win32">
+ <Configuration>Debug-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|x64">
+ <Configuration>Debug-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|Win32">
+ <Configuration>Release-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|x64">
+ <Configuration>Release-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|Win32">
+ <Configuration>Release-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|x64">
+ <Configuration>Release-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <Import Project="$(MhdW32Common)\hellobrowser-files.vcxproj" />
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{310F39BD-A2D6-44FF-8344-37ADD0524CBD}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>hellobrowser</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries Condition="$(Configuration.StartsWith('Debug'))">true</UseDebugLibraries>
+ <UseDebugLibraries Condition="! $(Configuration.StartsWith('Debug'))">false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization Condition="! $(Configuration.StartsWith('Debug'))">true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="$(MhdW32Common)common-build-settings.vcxproj" />
+ <Import Project="$(MhdW32Common)apps-build-settings.vcxproj" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ <Link />
+ <ProjectReference />
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/hellobrowser.vcxproj.filters
^
|
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <Import Project="$(MhdW32Common)hellobrowser-filters.vcxproj" />
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/largepost.vcxproj
^
|
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug-dll|Win32">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-dll|x64">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|Win32">
+ <Configuration>Debug-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|x64">
+ <Configuration>Debug-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|Win32">
+ <Configuration>Release-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|x64">
+ <Configuration>Release-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|Win32">
+ <Configuration>Release-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|x64">
+ <Configuration>Release-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <Import Project="$(MhdW32Common)\largepost-files.vcxproj" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{77A27E6D-9A39-40B8-961B-40E63DB7FA65}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>largepost</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries Condition="$(Configuration.StartsWith('Debug'))">true</UseDebugLibraries>
+ <UseDebugLibraries Condition="! $(Configuration.StartsWith('Debug'))">false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization Condition="! $(Configuration.StartsWith('Debug'))">true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="$(MhdW32Common)common-build-settings.vcxproj" />
+ <Import Project="$(MhdW32Common)apps-build-settings.vcxproj" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ <Link />
+ <ProjectReference />
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/libmicrohttpd.sln
^
|
@@ -0,0 +1,103 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.28803.156
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hellobrowser", "hellobrowser.vcxproj", "{310F39BD-A2D6-44FF-8344-37ADD0524CBD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A} = {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmicrohttpd", "libmicrohttpd.vcxproj", "{9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simplepost", "simplepost.vcxproj", "{294D5317-E983-4682-8DB5-678EA4645E11}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A} = {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "largepost", "largepost.vcxproj", "{77A27E6D-9A39-40B8-961B-40E63DB7FA65}"
+ ProjectSection(ProjectDependencies) = postProject
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A} = {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug-dll|Win32 = Debug-dll|Win32
+ Debug-dll|x64 = Debug-dll|x64
+ Debug-static|Win32 = Debug-static|Win32
+ Debug-static|x64 = Debug-static|x64
+ Release-dll|Win32 = Release-dll|Win32
+ Release-dll|x64 = Release-dll|x64
+ Release-static|Win32 = Release-static|Win32
+ Release-static|x64 = Release-static|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-dll|Win32.ActiveCfg = Debug-dll|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-dll|Win32.Build.0 = Debug-dll|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-dll|x64.ActiveCfg = Debug-dll|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-dll|x64.Build.0 = Debug-dll|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-static|Win32.ActiveCfg = Debug-static|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-static|Win32.Build.0 = Debug-static|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-static|x64.ActiveCfg = Debug-static|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Debug-static|x64.Build.0 = Debug-static|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-dll|Win32.ActiveCfg = Release-dll|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-dll|Win32.Build.0 = Release-dll|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-dll|x64.ActiveCfg = Release-dll|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-dll|x64.Build.0 = Release-dll|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-static|Win32.ActiveCfg = Release-static|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-static|Win32.Build.0 = Release-static|Win32
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-static|x64.ActiveCfg = Release-static|x64
+ {9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}.Release-static|x64.Build.0 = Release-static|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-dll|Win32.ActiveCfg = Debug-dll|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-dll|Win32.Build.0 = Debug-dll|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-dll|x64.ActiveCfg = Debug-dll|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-dll|x64.Build.0 = Debug-dll|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-static|Win32.ActiveCfg = Debug-static|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-static|Win32.Build.0 = Debug-static|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-static|x64.ActiveCfg = Debug-static|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Debug-static|x64.Build.0 = Debug-static|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-dll|Win32.ActiveCfg = Release-dll|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-dll|Win32.Build.0 = Release-dll|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-dll|x64.ActiveCfg = Release-dll|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-dll|x64.Build.0 = Release-dll|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-static|Win32.ActiveCfg = Release-static|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-static|Win32.Build.0 = Release-static|Win32
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-static|x64.ActiveCfg = Release-static|x64
+ {310F39BD-A2D6-44FF-8344-37ADD0524CBD}.Release-static|x64.Build.0 = Release-static|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-dll|Win32.ActiveCfg = Debug-dll|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-dll|Win32.Build.0 = Debug-dll|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-dll|x64.ActiveCfg = Debug-dll|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-dll|x64.Build.0 = Debug-dll|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-static|Win32.ActiveCfg = Debug-static|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-static|Win32.Build.0 = Debug-static|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-static|x64.ActiveCfg = Debug-static|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Debug-static|x64.Build.0 = Debug-static|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-dll|Win32.ActiveCfg = Release-dll|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-dll|Win32.Build.0 = Release-dll|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-dll|x64.ActiveCfg = Release-dll|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-dll|x64.Build.0 = Release-dll|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-static|Win32.ActiveCfg = Release-static|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-static|Win32.Build.0 = Release-static|Win32
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-static|x64.ActiveCfg = Release-static|x64
+ {294D5317-E983-4682-8DB5-678EA4645E11}.Release-static|x64.Build.0 = Release-static|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-dll|Win32.ActiveCfg = Debug-dll|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-dll|Win32.Build.0 = Debug-dll|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-dll|x64.ActiveCfg = Debug-dll|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-dll|x64.Build.0 = Debug-dll|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-static|Win32.ActiveCfg = Debug-static|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-static|Win32.Build.0 = Debug-static|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-static|x64.ActiveCfg = Debug-static|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Debug-static|x64.Build.0 = Debug-static|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-dll|Win32.ActiveCfg = Release-dll|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-dll|Win32.Build.0 = Release-dll|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-dll|x64.ActiveCfg = Release-dll|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-dll|x64.Build.0 = Release-dll|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-static|Win32.ActiveCfg = Release-static|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-static|Win32.Build.0 = Release-static|Win32
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-static|x64.ActiveCfg = Release-static|x64
+ {77A27E6D-9A39-40B8-961B-40E63DB7FA65}.Release-static|x64.Build.0 = Release-static|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/libmicrohttpd.vcxproj
^
|
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug-dll|Win32">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-dll|x64">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|Win32">
+ <Configuration>Debug-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|x64">
+ <Configuration>Debug-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|Win32">
+ <Configuration>Release-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|x64">
+ <Configuration>Release-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|Win32">
+ <Configuration>Release-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|x64">
+ <Configuration>Release-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <Import Project="$(MhdW32Common)\libmicrohttpd-files.vcxproj" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9CFB0342-A9E7-483E-BEE5-A1DE22584C5A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>libmicrohttpd</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType Condition="$(Configuration.EndsWith('-static'))">StaticLibrary</ConfigurationType>
+ <ConfigurationType Condition="! $(Configuration.EndsWith('-static'))">DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries Condition="$(Configuration.StartsWith('Debug'))">true</UseDebugLibraries>
+ <UseDebugLibraries Condition="! $(Configuration.StartsWith('Debug'))">false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization Condition="! $(Configuration.StartsWith('Debug'))">true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="$(MhdW32Common)common-build-settings.vcxproj" />
+ <Import Project="$(MhdW32Common)libmicrohttpd-build-settings.vcxproj" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ <Link />
+ <Lib />
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/libmicrohttpd.vcxproj.filters
^
|
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <Import Project="$(MhdW32Common)libmicrohttpd-filters.vcxproj" />
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Added |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/VS2019/simplepost.vcxproj
^
|
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)..\common\vs_dirs.props" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug-dll|Win32">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-dll|x64">
+ <Configuration>Debug-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|Win32">
+ <Configuration>Debug-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug-static|x64">
+ <Configuration>Debug-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|Win32">
+ <Configuration>Release-dll</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-dll|x64">
+ <Configuration>Release-dll</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|Win32">
+ <Configuration>Release-static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release-static|x64">
+ <Configuration>Release-static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <Import Project="$(MhdW32Common)\simplepost-files.vcxproj" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{294D5317-E983-4682-8DB5-678EA4645E11}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>simplepost</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries Condition="$(Configuration.StartsWith('Debug'))">true</UseDebugLibraries>
+ <UseDebugLibraries Condition="! $(Configuration.StartsWith('Debug'))">false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization Condition="! $(Configuration.StartsWith('Debug'))">true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <Import Project="$(MhdW32Common)common-build-settings.vcxproj" />
+ <Import Project="$(MhdW32Common)apps-build-settings.vcxproj" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ <Link />
+ <ProjectReference />
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/common/MHD_config.h
^
|
@@ -9,11 +9,29 @@
/* Define if MS VC compiler is used */
#define MSVC 1
+/* Define that MS VC does not support VLAs */
+#ifndef __clang__
+#define __STDC_NO_VLA__ 1
+#endif
+
+/* If clang is used then variable-length arrays are supported. */
+#ifdef __clang__
+#define HAVE_C_VARARRAYS 1
+#endif
+
/* Define to 1 if your C compiler supports inline functions. */
#define INLINE_FUNC 1
/* Define to prefix which will be used with MHD inline functions. */
-#define _MHD_inline static __forceinline
+#define _MHD_static_inline static __forceinline
+
+#ifdef __clang__
+/* Define to 1 if you have __builtin_bswap32() builtin function */
+#define MHD_HAVE___BUILTIN_BSWAP32 1
+
+/* Define to 1 if you have __builtin_bswap64() builtin function */
+#define MHD_HAVE___BUILTIN_BSWAP64 1
+#endif /* __clang__ */
/* *** MHD configuration *** */
@@ -70,6 +88,9 @@
/* Define to 1 if you have the usable `calloc' function. */
#define HAVE_CALLOC 1
+/* Define if you have usable assert() and assert.h */
+#define HAVE_ASSERT 1
+
#if _MSC_VER >= 1900 /* snprintf() supported natively since VS2015 */
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
@@ -80,6 +101,33 @@
#define HAVE_INTTYPES_H 1
#endif
+#if _MSC_VER + 0 >= 1800 /* VS 2013 and later */
+/* Define to 1 if you have the <stdbool.h> header file and <stdbool.h> defines
+ 'bool' type. */
+#define HAVE_STDBOOL_H 1
+#else /* before VS 2013 */
+
+/* Define to type name which will be used as boolean type. */
+#define bool int
+
+/* Define to value interpreted by compiler as boolean "false", if "false" is
+ not defined by system headers. */
+#define false 0
+
+/* Define to value interpreted by compiler as boolean "true", if "true" is not
+ defined by system headers. */
+#define true (!0)
+#endif /* before VS 2013 */
+
+/* Define to 1 if you have the `getsockname' function. */
+#define HAVE_GETSOCKNAME 1
+
+/* Define if you have usable `getsockname' function. */
+#define MHD_USE_GETSOCKNAME 1
+
+/* Define to 1 if your compiler supports __func__ magic-macro. */
+#define HAVE___FUNC__ 1
+
/* *** Headers information *** */
/* Not really important as not used by code currently */
@@ -102,6 +150,9 @@
/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1
+/* Define to 1 if you have the <sdkddkver.h> header file. */
+#define HAVE_SDKDDKVER_H 1
+
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
@@ -132,23 +183,8 @@
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
-#if _MSC_VER+0 >= 1800 /* VS 2013 and later */
-/* Define to 1 if you have the <stdbool.h> header file and <stdbool.h> defines
- 'bool' type. */
-#define HAVE_STDBOOL_H 1
-#else /* before VS 2013 */
-
-/* Define to type name which will be used as boolean type. */
-#define bool int
-
-/* Define to value interpreted by compiler as boolean "false", if "false" is
- not defined by system headers. */
-#define false 0
-
-/* Define to value interpreted by compiler as boolean "true", if "true" is not
- defined by system headers. */
-#define true (!0)
-#endif /* before VS 2013 */
+/* Define to 1 if you have the <windows.h> header file. */
+#define HAVE_WINDOWS_H 1
/* *** Other useful staff *** */
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/common/common-build-settings.vcxproj
^
|
@@ -74,6 +74,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<SmallerTypeCheck>true</SmallerTypeCheck>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -87,6 +88,7 @@
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -97,4 +99,20 @@
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+ <Link>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Lib>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+ <Link>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <Lib>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ </ItemDefinitionGroup>
</Project>
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/common/libmicrohttpd-files.vcxproj
^
|
@@ -8,6 +8,7 @@
<ClCompile Include="$(MhdSrc)microhttpd\digestauth.c" />
<ClCompile Include="$(MhdSrc)microhttpd\internal.c" />
<ClCompile Include="$(MhdSrc)microhttpd\md5.c" />
+ <ClCompile Include="$(MhdSrc)microhttpd\sha256.c" />
<ClCompile Include="$(MhdSrc)microhttpd\memorypool.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_mono_clock.c" />
<ClCompile Include="$(MhdSrc)microhttpd\postprocessor.c" />
@@ -17,6 +18,7 @@
<ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_threads.c" />
+ <ClCompile Include="$(MhdSrc)microhttpd\mhd_send.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_sockets.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_itc.c" />
<ClCompile Include="$(MhdSrc)microhttpd\mhd_compat.c" />
@@ -30,7 +32,10 @@
<ClInclude Include="$(MhdSrc)microhttpd\connection.h" />
<ClInclude Include="$(MhdSrc)microhttpd\internal.h" />
<ClInclude Include="$(MhdSrc)microhttpd\md5.h" />
+ <ClInclude Include="$(MhdSrc)microhttpd\sha256.h" />
<ClInclude Include="$(MhdSrc)microhttpd\memorypool.h" />
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_assert.h" />
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_bithelpers.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_byteorder.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_limits.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_mono_clock.h" />
@@ -40,6 +45,7 @@
<ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_threads.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_locks.h" />
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_send.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_sockets.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_itc.h" />
<ClInclude Include="$(MhdSrc)microhttpd\mhd_itc_types.h" />
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/common/libmicrohttpd-filters.vcxproj
^
|
@@ -57,6 +57,12 @@
<ClCompile Include="$(MhdSrc)microhttpd\md5.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="$(MhdSrc)microhttpd\sha256.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClInclude Include="$(MhdSrc)microhttpd\sha256.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
<ClCompile Include="$(MhdSrc)microhttpd\memorypool.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -96,9 +102,15 @@
<ClInclude Include="$(MhdSrc)microhttpd\tsearch.h">
<Filter>Source Files</Filter>
</ClInclude>
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_assert.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
<ClInclude Include="$(MhdSrc)microhttpd\mhd_limits.h">
<Filter>Source Files</Filter>
</ClInclude>
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_bithelpers.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
<ClInclude Include="$(MhdSrc)microhttpd\mhd_byteorder.h">
<Filter>Source Files</Filter>
</ClInclude>
@@ -141,6 +153,12 @@
<ClCompile Include="$(MhdSrc)microhttpd\mhd_itc.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClInclude Include="$(MhdSrc)microhttpd\mhd_send.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ <ClCompile Include="$(MhdSrc)microhttpd\mhd_send.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClInclude Include="$(MhdSrc)microhttpd\mhd_compat.h">
<Filter>Source Files</Filter>
</ClInclude>
|
[-]
[+]
|
Changed |
_service:tar_git:libmicrohttpd-0.9.73.tar.gz/libmicrohttpd/w32/common/microhttpd_dll_res_vc.rc.in
^
|
@@ -23,15 +23,15 @@
VALUE "ProductName", "GNU libmicrohttpd\0"
VALUE "ProductVersion", "@PACKAGE_VERSION@\0"
VALUE "FileVersion", "@PACKAGE_VERSION@\0"
- VALUE "FileDescription", "GNU libmicrohttpd dll for Windows (VC build)\0"
+ VALUE "FileDescription", "GNU libmicrohttpd DLL for Windows (VC build)\0"
VALUE "InternalName", "libmicrohttpd\0"
#if defined(_DEBUG)
- VALUE "OriginalFilename", "libmicrohttpd_d.dll\0"
+ VALUE "OriginalFilename", "libmicrohttpd-dll_d.dll\0"
#else
- VALUE "OriginalFilename", "libmicrohttpd.dll\0"
+ VALUE "OriginalFilename", "libmicrohttpd-dll.dll\0"
#endif
VALUE "CompanyName", "Free Software Foundation\0"
- VALUE "LegalCopyright", "Copyright (C) 2007-2015 Christian Grothoff and project contributors\0"
+ VALUE "LegalCopyright", "Copyright (C) 2007-2020 Christian Grothoff, Evgeny Grin and project contributors\0"
VALUE "Comments", "http://www.gnu.org/software/libmicrohttpd/\0"
END
END
|