mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Forked off Anti-Web and made axhttpd
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@51 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
396d340778
commit
8213b750a1
7
Makefile
7
Makefile
@ -34,8 +34,7 @@ RELEASE=axTLS-$(VERSION)
|
|||||||
# standard version
|
# standard version
|
||||||
target:
|
target:
|
||||||
$(MAKE) -C ssl
|
$(MAKE) -C ssl
|
||||||
ifdef CONFIG_AWHTTPD
|
ifdef CONFIG_AXHTTPD
|
||||||
$(MAKE) -C httpd untar_web_server
|
|
||||||
$(MAKE) -C httpd
|
$(MAKE) -C httpd
|
||||||
endif
|
endif
|
||||||
ifdef CONFIG_BINDINGS
|
ifdef CONFIG_BINDINGS
|
||||||
@ -72,12 +71,12 @@ install: $(PREFIX) all
|
|||||||
chmod 755 $(PREFIX)/lib/libax*
|
chmod 755 $(PREFIX)/lib/libax*
|
||||||
-@install -m 755 $(STAGE)/ax* $(PREFIX)/bin > /dev/null 2>&1
|
-@install -m 755 $(STAGE)/ax* $(PREFIX)/bin > /dev/null 2>&1
|
||||||
-@install -m 755 $(STAGE)/axtlsp.pm `perl -e 'use Config; print $$Config{installarchlib};'` > /dev/null 2>&1
|
-@install -m 755 $(STAGE)/axtlsp.pm `perl -e 'use Config; print $$Config{installarchlib};'` > /dev/null 2>&1
|
||||||
-@install -m 755 $(STAGE)/awhttpd* $(PREFIX)/bin > /dev/null 2>&1
|
-@install -m 755 $(STAGE)/axhttpd* $(PREFIX)/bin > /dev/null 2>&1
|
||||||
|
|
||||||
installclean:
|
installclean:
|
||||||
-@rm $(PREFIX)/lib/libax* > /dev/null 2>&1
|
-@rm $(PREFIX)/lib/libax* > /dev/null 2>&1
|
||||||
-@rm $(PREFIX)/bin/ax* > /dev/null 2>&1
|
-@rm $(PREFIX)/bin/ax* > /dev/null 2>&1
|
||||||
-@rm $(PREFIX)/bin/awhttpd* > /dev/null 2>&1
|
-@rm $(PREFIX)/bin/axhttpd* > /dev/null 2>&1
|
||||||
-@rm `perl -e 'use Config; print $$Config{installarchlib};'`/axtlsp.pm > /dev/null 2>&1
|
-@rm `perl -e 'use Config; print $$Config{installarchlib};'`/axtlsp.pm > /dev/null 2>&1
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
11
README
11
README
@ -9,7 +9,7 @@ This is a guide to get a small SSL web-server up and running quickly.
|
|||||||
########################################################################
|
########################################################################
|
||||||
The axTLS project is an SSL client/server library using the TLSv1 protocol.
|
The axTLS project is an SSL client/server library using the TLSv1 protocol.
|
||||||
It is designed to be small and fast, and is suited to embedded projects. A web
|
It is designed to be small and fast, and is suited to embedded projects. A web
|
||||||
server is included (called Anti-Web).
|
server is included.
|
||||||
|
|
||||||
The web server + SSL library is around 50-60kB and is configurable for
|
The web server + SSL library is around 50-60kB and is configurable for
|
||||||
features or size.
|
features or size.
|
||||||
@ -32,8 +32,8 @@ the extracted directory and typing:
|
|||||||
Select your platform type, save the configuration, exit, and then
|
Select your platform type, save the configuration, exit, and then
|
||||||
type "make" again.
|
type "make" again.
|
||||||
|
|
||||||
If all goes well, you should end up with an executable called "awhttpd" (or
|
If all goes well, you should end up with an executable called "axhttpd" (or
|
||||||
awhttpd.exe) in the _stage directory.
|
axhttpd.exe) in the _stage directory.
|
||||||
|
|
||||||
To play with all the various axTLS options, type:
|
To play with all the various axTLS options, type:
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ Save the new configuration and rebuild.
|
|||||||
|
|
||||||
To run it, go to the _stage directory, and type (as superuser):
|
To run it, go to the _stage directory, and type (as superuser):
|
||||||
|
|
||||||
> awhttpd
|
> axhttpd
|
||||||
|
|
||||||
And then point your browser at:
|
And then point your browser at:
|
||||||
|
|
||||||
@ -61,9 +61,6 @@ http://127.0.0.1
|
|||||||
|
|
||||||
to see the same page unencrypted.
|
to see the same page unencrypted.
|
||||||
|
|
||||||
See the README in the httpd directory from more configuration information on
|
|
||||||
Anti-Web.
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# The axssl utilities
|
# The axssl utilities
|
||||||
########################################################################
|
########################################################################
|
||||||
|
@ -107,11 +107,11 @@ config CONFIG_EXTRA_LDFLAGS_OPTIONS
|
|||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
source ssl/Config.in
|
source ssl/Config.in
|
||||||
config CONFIG_AWHTTPD
|
config CONFIG_AXHTTPD
|
||||||
bool "Enable HTTP/HTTPS Web Server"
|
bool "Enable HTTP/HTTPS Web Server"
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Build the AWHTTPD web server
|
Build the AXHTTPD web server
|
||||||
|
|
||||||
source httpd/Config.in
|
source httpd/Config.in
|
||||||
source bindings/Config.in
|
source bindings/Config.in
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<jmeterTestPlan version="1.2" properties="1.8">
|
<jmeterTestPlan version="1.2" properties="1.8">
|
||||||
<hashTree>
|
<hashTree>
|
||||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="awhttpd Test Plan" enabled="true">
|
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="axhttpd Test Plan" enabled="true">
|
||||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
<collectionProp name="Arguments.arguments"/>
|
<collectionProp name="Arguments.arguments"/>
|
||||||
</elementProp>
|
</elementProp>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||||
<ROW Component="New_Folder" ComponentId="{2AD064CD-A20E-40FD-9233-CF8732C8F54D}" Directory_="New_Folder_2_DIR" Attributes="0"/>
|
<ROW Component="New_Folder" ComponentId="{2AD064CD-A20E-40FD-9233-CF8732C8F54D}" Directory_="New_Folder_2_DIR" Attributes="0"/>
|
||||||
<ROW Component="awhttpd.exe" ComponentId="{0AEFFA20-29FA-4304-8227-F9ED0E6B8A0A}" Directory_="APPDIR" Attributes="0" KeyPath="awhttpd.exe" FullKeyPath="APPDIR\awhttpd.exe"/>
|
<ROW Component="axhttpd.exe" ComponentId="{0AEFFA20-29FA-4304-8227-F9ED0E6B8A0A}" Directory_="APPDIR" Attributes="0" KeyPath="axhttpd.exe" FullKeyPath="APPDIR\axhttpd.exe"/>
|
||||||
<ROW Component="axssl.csharp.exe" ComponentId="{B9373428-79F5-4D77-8924-48D23EF3870E}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.csharp.exe" FullKeyPath="APPDIR\axssl.csharp.exe"/>
|
<ROW Component="axssl.csharp.exe" ComponentId="{B9373428-79F5-4D77-8924-48D23EF3870E}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.csharp.exe" FullKeyPath="APPDIR\axssl.csharp.exe"/>
|
||||||
<ROW Component="axssl.exe" ComponentId="{E1E96774-7BFC-45B9-BA33-FC0C631921FD}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.exe" FullKeyPath="APPDIR\axssl.exe"/>
|
<ROW Component="axssl.exe" ComponentId="{E1E96774-7BFC-45B9-BA33-FC0C631921FD}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.exe" FullKeyPath="APPDIR\axssl.exe"/>
|
||||||
<ROW Component="axssl.vbnet.exe" ComponentId="{31F03DA9-E099-4BBD-88B7-4ABBC9F77EFB}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.vbnet.exe" FullKeyPath="APPDIR\axssl.vbnet.exe"/>
|
<ROW Component="axssl.vbnet.exe" ComponentId="{31F03DA9-E099-4BBD-88B7-4ABBC9F77EFB}" Directory_="APPDIR" Attributes="0" KeyPath="axssl.vbnet.exe" FullKeyPath="APPDIR\axssl.vbnet.exe"/>
|
||||||
@ -59,12 +59,12 @@
|
|||||||
<ROW Component="wcprops" ComponentId="{4106AB01-565E-4281-97AE-96EC1F865899}" Directory_="wcprops_DIR" Attributes="0"/>
|
<ROW Component="wcprops" ComponentId="{4106AB01-565E-4281-97AE-96EC1F865899}" Directory_="wcprops_DIR" Attributes="0"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="awhttpd.exe axssl.csharp.exe axssl.exe axssl.vbnet.exe axtls.dll axtls.jar axtlsj.dll favicon.ico bigint.h test_cgi.php New_Folder dir_wcprops crypto_2600des.gif.svn_base crypto_2600des.gif.svn_work crypto_2600des.gif.svn_base_1 prop_base props text_base wcprops crypto_2600des.gif.svn_work_1 crypto_2600des.gif"/>
|
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="axhttpd.exe axssl.csharp.exe axssl.exe axssl.vbnet.exe axtls.dll axtls.jar axtlsj.dll favicon.ico bigint.h test_cgi.php New_Folder dir_wcprops crypto_2600des.gif.svn_base crypto_2600des.gif.svn_work crypto_2600des.gif.svn_base_1 prop_base props text_base wcprops crypto_2600des.gif.svn_work_1 crypto_2600des.gif"/>
|
||||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||||
<ROW File="README.txt" Component_="dir_wcprops" FileName="README.txt" Attributes="1" SourcePath="..\www\crypto_files\.svn\README.txt" SelfReg="false" Sequence="43"/>
|
<ROW File="README.txt" Component_="dir_wcprops" FileName="README.txt" Attributes="1" SourcePath="..\www\crypto_files\.svn\README.txt" SelfReg="false" Sequence="43"/>
|
||||||
<ROW File="awhttpd.exe" Component_="awhttpd.exe" FileName="awhttpd.exe" Attributes="0" SourcePath="..\_stage\awhttpd.exe" SelfReg="false" Sequence="1"/>
|
<ROW File="axhttpd.exe" Component_="axhttpd.exe" FileName="axhttpd.exe" Attributes="0" SourcePath="..\_stage\axhttpd.exe" SelfReg="false" Sequence="1"/>
|
||||||
<ROW File="axssl.csharp.exe" Component_="axssl.csharp.exe" FileName="axsslc~1.exe|axssl.csharp.exe" Attributes="0" SourcePath="..\_stage\axssl.csharp.exe" SelfReg="false" Sequence="2"/>
|
<ROW File="axssl.csharp.exe" Component_="axssl.csharp.exe" FileName="axsslc~1.exe|axssl.csharp.exe" Attributes="0" SourcePath="..\_stage\axssl.csharp.exe" SelfReg="false" Sequence="2"/>
|
||||||
<ROW File="axssl.exe" Component_="axssl.exe" FileName="axssl.exe" Attributes="0" SourcePath="..\_stage\axssl.exe" SelfReg="false" Sequence="3"/>
|
<ROW File="axssl.exe" Component_="axssl.exe" FileName="axssl.exe" Attributes="0" SourcePath="..\_stage\axssl.exe" SelfReg="false" Sequence="3"/>
|
||||||
<ROW File="axssl.vbnet.exe" Component_="axssl.vbnet.exe" FileName="axsslv~1.exe|axssl.vbnet.exe" Attributes="0" SourcePath="..\_stage\axssl.vbnet.exe" SelfReg="false" Sequence="4"/>
|
<ROW File="axssl.vbnet.exe" Component_="axssl.vbnet.exe" FileName="axsslv~1.exe|axssl.vbnet.exe" Attributes="0" SourcePath="..\_stage\axssl.vbnet.exe" SelfReg="false" Sequence="4"/>
|
||||||
@ -199,7 +199,7 @@
|
|||||||
<ATTRIBUTE name="Package" value="1"/>
|
<ATTRIBUTE name="Package" value="1"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
||||||
<ROW Shortcut="awhttpd.exe" Directory_="SHORTCUTDIR" Name="awhttpd" Component_="awhttpd.exe" Target="[#awhttpd.exe]" Description="awhttpd.exe" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
<ROW Shortcut="axhttpd.exe" Directory_="SHORTCUTDIR" Name="axhttpd" Component_="axhttpd.exe" Target="[#axhttpd.exe]" Description="axhttpd.exe" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
||||||
<ROW Shortcut="axssl_client" Directory_="SHORTCUTDIR" Name="axsslc~1|axssl client" Component_="axssl.exe" Target="[#axssl.exe]" Arguments="s_client" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
<ROW Shortcut="axssl_client" Directory_="SHORTCUTDIR" Name="axsslc~1|axssl client" Component_="axssl.exe" Target="[#axssl.exe]" Arguments="s_client" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
||||||
<ROW Shortcut="axssl_server" Directory_="SHORTCUTDIR" Name="axssls~1|axssl server" Component_="axssl.exe" Target="[#axssl.exe]" Arguments="s_server" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
<ROW Shortcut="axssl_server" Directory_="SHORTCUTDIR" Name="axssls~1|axssl server" Component_="axssl.exe" Target="[#axssl.exe]" Arguments="s_server" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
@ -43,9 +43,8 @@ CONFIG_USE_DEV_URANDOM=y
|
|||||||
# CONFIG_WIN32_USE_CRYPTO_LIB is not set
|
# CONFIG_WIN32_USE_CRYPTO_LIB is not set
|
||||||
# CONFIG_PERFORMANCE_TESTING is not set
|
# CONFIG_PERFORMANCE_TESTING is not set
|
||||||
# CONFIG_SSL_TEST is not set
|
# CONFIG_SSL_TEST is not set
|
||||||
# CONFIG_AWHTTPD is not set
|
# CONFIG_AXHTTPD is not set
|
||||||
# CONFIG_HTTP_STATIC_BUILD is not set
|
# CONFIG_HTTP_STATIC_BUILD is not set
|
||||||
# CONFIG_HTTP_HAS_SSL is not set
|
|
||||||
CONFIG_HTTP_HTTPS_PORT=0
|
CONFIG_HTTP_HTTPS_PORT=0
|
||||||
CONFIG_HTTP_SESSION_CACHE_SIZE=0
|
CONFIG_HTTP_SESSION_CACHE_SIZE=0
|
||||||
CONFIG_HTTP_WEBROOT=""
|
CONFIG_HTTP_WEBROOT=""
|
||||||
|
@ -47,13 +47,12 @@ CONFIG_SSL_MAX_CERTS=2
|
|||||||
CONFIG_WIN32_USE_CRYPTO_LIB=y
|
CONFIG_WIN32_USE_CRYPTO_LIB=y
|
||||||
# CONFIG_PERFORMANCE_TESTING is not set
|
# CONFIG_PERFORMANCE_TESTING is not set
|
||||||
# CONFIG_SSL_TEST is not set
|
# CONFIG_SSL_TEST is not set
|
||||||
CONFIG_AWHTTPD=y
|
CONFIG_AXHTTPD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Awhttpd Configuration
|
# Awhttpd Configuration
|
||||||
#
|
#
|
||||||
# CONFIG_HTTP_STATIC_BUILD is not set
|
# CONFIG_HTTP_STATIC_BUILD is not set
|
||||||
CONFIG_HTTP_HAS_SSL=y
|
|
||||||
CONFIG_HTTP_HTTPS_PORT=443
|
CONFIG_HTTP_HTTPS_PORT=443
|
||||||
CONFIG_HTTP_WEBROOT="www"
|
CONFIG_HTTP_WEBROOT="www"
|
||||||
CONFIG_HTTP_PORT=80
|
CONFIG_HTTP_PORT=80
|
||||||
|
@ -3,26 +3,19 @@
|
|||||||
# see scripts/config/Kconfig-language.txt
|
# see scripts/config/Kconfig-language.txt
|
||||||
#
|
#
|
||||||
|
|
||||||
menu "Awhttpd Configuration"
|
menu "Axhttpd Configuration"
|
||||||
depends on CONFIG_AWHTTPD
|
depends on CONFIG_AXHTTPD
|
||||||
|
|
||||||
config CONFIG_HTTP_STATIC_BUILD
|
config CONFIG_HTTP_STATIC_BUILD
|
||||||
bool "Static Build"
|
bool "Static Build"
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Select y if you want awhttp to be a static build (i.e. don't use the
|
Select y if you want axhttp to be a static build (i.e. don't use the
|
||||||
axtls shared library or dll).
|
axtls shared library or dll).
|
||||||
|
|
||||||
config CONFIG_HTTP_HAS_SSL
|
|
||||||
bool "Use SSL"
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Build the HTTP server with SSL capability
|
|
||||||
|
|
||||||
config CONFIG_HTTP_HTTPS_PORT
|
config CONFIG_HTTP_HTTPS_PORT
|
||||||
int "HTTPS port"
|
int "HTTPS port"
|
||||||
default 443
|
default 443
|
||||||
depends on CONFIG_HTTP_HAS_SSL
|
|
||||||
help
|
help
|
||||||
The port number of the HTTPS server.
|
The port number of the HTTPS server.
|
||||||
|
|
||||||
@ -31,7 +24,6 @@ config CONFIG_HTTP_HTTPS_PORT
|
|||||||
config CONFIG_HTTP_SESSION_CACHE_SIZE
|
config CONFIG_HTTP_SESSION_CACHE_SIZE
|
||||||
int "SSL session cache size"
|
int "SSL session cache size"
|
||||||
default 5
|
default 5
|
||||||
depends on CONFIG_HTTP_HAS_SSL
|
|
||||||
help
|
help
|
||||||
The size of the SSL session cache.
|
The size of the SSL session cache.
|
||||||
|
|
||||||
@ -44,7 +36,7 @@ config CONFIG_HTTP_WEBROOT
|
|||||||
default "../www" if !CONFIG_PLATFORM_WIN32
|
default "../www" if !CONFIG_PLATFORM_WIN32
|
||||||
default "..\\www" if CONFIG_PLATFORM_WIN32
|
default "..\\www" if CONFIG_PLATFORM_WIN32
|
||||||
help
|
help
|
||||||
The location of the web root in relation to awhttpd. This is
|
The location of the web root in relation to axhttpd. This is
|
||||||
the directory where index.html lives.
|
the directory where index.html lives.
|
||||||
|
|
||||||
config CONFIG_HTTP_PORT
|
config CONFIG_HTTP_PORT
|
||||||
@ -72,7 +64,7 @@ config CONFIG_HTTP_CGI_EXTENSION
|
|||||||
default ".php"
|
default ".php"
|
||||||
depends on CONFIG_HTTP_HAS_CGI
|
depends on CONFIG_HTTP_HAS_CGI
|
||||||
help
|
help
|
||||||
Tell awhhtp what file extension is used for CGI
|
Tell axhhtp what file extension is used for CGI
|
||||||
|
|
||||||
config CONFIG_HTTP_DIRECTORIES
|
config CONFIG_HTTP_DIRECTORIES
|
||||||
bool "Enable Directory Listing"
|
bool "Enable Directory Listing"
|
||||||
@ -101,14 +93,14 @@ config CONFIG_HTTP_VERBOSE
|
|||||||
default y if CONFIG_SSL_FULL_MODE
|
default y if CONFIG_SSL_FULL_MODE
|
||||||
default n if !CONFIG_SSL_FULL_MODE
|
default n if !CONFIG_SSL_FULL_MODE
|
||||||
help
|
help
|
||||||
Enable extra statements used when using awhttpd.
|
Enable extra statements used when using axhttpd.
|
||||||
|
|
||||||
config CONFIG_HTTP_IS_DAEMON
|
config CONFIG_HTTP_IS_DAEMON
|
||||||
bool "Run as a daemon"
|
bool "Run as a daemon"
|
||||||
default n
|
default n
|
||||||
depends on !CONFIG_PLATFORM_WIN32
|
depends on !CONFIG_PLATFORM_WIN32
|
||||||
help
|
help
|
||||||
Run awhttpd as a background process.
|
Run axhttpd as a background process.
|
||||||
|
|
||||||
Does not work under Win32
|
Does not work under Win32
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ include ../config/makefile.conf
|
|||||||
ifndef CONFIG_PLATFORM_WIN32
|
ifndef CONFIG_PLATFORM_WIN32
|
||||||
|
|
||||||
ifdef CONFIG_PLATFORM_CYGWIN
|
ifdef CONFIG_PLATFORM_CYGWIN
|
||||||
TARGET=../$(STAGE)/awhttpd.exe
|
TARGET=../$(STAGE)/axhttpd.exe
|
||||||
else
|
else
|
||||||
TARGET=../$(STAGE)/awhttpd
|
TARGET=../$(STAGE)/axhttpd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_HTTP_STATIC_BUILD
|
ifdef CONFIG_HTTP_STATIC_BUILD
|
||||||
@ -38,7 +38,7 @@ endif
|
|||||||
CFLAGS += -I../ssl
|
CFLAGS += -I../ssl
|
||||||
|
|
||||||
else # win32 build
|
else # win32 build
|
||||||
TARGET=../$(STAGE)/awhttpd.exe
|
TARGET=../$(STAGE)/axhttpd.exe
|
||||||
|
|
||||||
ifdef CONFIG_HTTP_STATIC_BUILD
|
ifdef CONFIG_HTTP_STATIC_BUILD
|
||||||
LIBS=../$(STAGE)/axtls.static.lib ..\\config\\axtls.res
|
LIBS=../$(STAGE)/axtls.static.lib ..\\config\\axtls.res
|
||||||
@ -51,31 +51,16 @@ ifndef CONFIG_AWHTTPD
|
|||||||
web_server:
|
web_server:
|
||||||
else
|
else
|
||||||
|
|
||||||
untar_web_server: awhttpd/Makefile
|
|
||||||
|
|
||||||
awhttpd/Makefile:
|
|
||||||
tar xvf awhttpd-3.0.7.tar
|
|
||||||
cat awhttpd.patch | patch -p0
|
|
||||||
|
|
||||||
web_server : $(TARGET)
|
web_server : $(TARGET)
|
||||||
|
|
||||||
OBJ= \
|
OBJ= \
|
||||||
cgi.o \
|
|
||||||
conn.o \
|
conn.o \
|
||||||
main.o \
|
main.o \
|
||||||
net.o \
|
net.o \
|
||||||
proc.o \
|
proc.o \
|
||||||
socket.o \
|
socket.o \
|
||||||
errors.o \
|
|
||||||
misc.o \
|
misc.o \
|
||||||
urldecode.o \
|
mime_types.o
|
||||||
mime_types.o \
|
|
||||||
index.o \
|
|
||||||
urlencode.o \
|
|
||||||
permcheck.o
|
|
||||||
|
|
||||||
%.o : awhttpd/%.c ../config/.config
|
|
||||||
$(CC) -c $(CFLAGS) $<
|
|
||||||
|
|
||||||
ifndef CONFIG_PLATFORM_WIN32
|
ifndef CONFIG_PLATFORM_WIN32
|
||||||
|
|
||||||
@ -91,10 +76,6 @@ endif
|
|||||||
endif
|
endif
|
||||||
else # Win32
|
else # Win32
|
||||||
|
|
||||||
OBJ:=$(OBJ:.o=.obj)
|
|
||||||
%.obj : awhttpd/%.c
|
|
||||||
$(CC) $(CFLAGS) $<
|
|
||||||
|
|
||||||
$(TARGET): $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
ifdef CONFIG_HTTP_NO_SSL
|
ifdef CONFIG_HTTP_NO_SSL
|
||||||
$(LD) $(LDFLAGS) /out:$@ $(OBJ)
|
$(LD) $(LDFLAGS) /out:$@ $(OBJ)
|
||||||
@ -106,5 +87,4 @@ endif # CONFIG_AWHTTPD
|
|||||||
|
|
||||||
clean::
|
clean::
|
||||||
-@rm -f $(TARGET)*
|
-@rm -f $(TARGET)*
|
||||||
-@rm -fr awhttpd
|
|
||||||
|
|
||||||
|
6
httpd/README
Normal file
6
httpd/README
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
axhttpd is a small embedded web server using the axTLS library.
|
||||||
|
|
||||||
|
It is based quite closely on the web server written by Doug Currie (original
|
||||||
|
version is here: http://www.hcsw.org/awhttpd).
|
||||||
|
|
Binary file not shown.
2371
httpd/awhttpd.patch
2371
httpd/awhttpd.patch
File diff suppressed because it is too large
Load Diff
164
httpd/axhttp.h
Normal file
164
httpd/axhttp.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "os_port.h"
|
||||||
|
#include "ssl.h"
|
||||||
|
|
||||||
|
#define BACKLOG 15
|
||||||
|
#define VERSION "3.0.7"
|
||||||
|
#ifdef CONFIG_HTTP_HAS_IPV6
|
||||||
|
#define HAVE_IPV6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAXFILEPATH 1024
|
||||||
|
#define MAXIPLEN 45
|
||||||
|
#define MAXREQUESTLENGTH 1024
|
||||||
|
#define MAXCGIARGS 100
|
||||||
|
#define BLOCKSIZE 4096
|
||||||
|
|
||||||
|
#define INITIAL_CONNECTION_SLOTS 10
|
||||||
|
#define CONFIG_HTTP_DEFAULT_SSL_OPTIONS 0
|
||||||
|
|
||||||
|
#define STATE_WANT_TO_READ_HEAD 1
|
||||||
|
#define STATE_WANT_TO_SEND_HEAD 2
|
||||||
|
#define STATE_WANT_TO_READ_FILE 3
|
||||||
|
#define STATE_WANT_TO_SEND_FILE 4
|
||||||
|
#define STATE_DOING_DIR 5
|
||||||
|
|
||||||
|
#define TYPE_GET 0
|
||||||
|
#define TYPE_HEAD 1
|
||||||
|
#define TYPE_POST 2
|
||||||
|
|
||||||
|
struct connstruct
|
||||||
|
{
|
||||||
|
struct connstruct *next;
|
||||||
|
|
||||||
|
int state;
|
||||||
|
int reqtype;
|
||||||
|
|
||||||
|
int networkdesc;
|
||||||
|
int filedesc;
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE dirp;
|
||||||
|
WIN32_FIND_DATA file_data;
|
||||||
|
#else
|
||||||
|
DIR *dirp;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
time_t timeout;
|
||||||
|
char ip[MAXIPLEN];
|
||||||
|
char actualfile[MAXREQUESTLENGTH];
|
||||||
|
char filereq[MAXREQUESTLENGTH];
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
char cgiargs[MAXREQUESTLENGTH];
|
||||||
|
char cgiscriptinfo[MAXREQUESTLENGTH];
|
||||||
|
char cgipathinfo[MAXREQUESTLENGTH];
|
||||||
|
#endif
|
||||||
|
char virtualhostreq[MAXREQUESTLENGTH];
|
||||||
|
|
||||||
|
int numbytes;
|
||||||
|
char databuf[BLOCKSIZE];
|
||||||
|
|
||||||
|
unsigned char is_ssl;
|
||||||
|
unsigned char close_when_done;
|
||||||
|
unsigned char modified_since;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct serverstruct
|
||||||
|
{
|
||||||
|
struct serverstruct *next;
|
||||||
|
int sd;
|
||||||
|
int is_ssl;
|
||||||
|
SSLCTX *ssl_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cgiextstruct
|
||||||
|
{
|
||||||
|
struct cgiextstruct *next;
|
||||||
|
char *ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct indexstruct
|
||||||
|
{
|
||||||
|
struct indexstruct *next;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global prototypes
|
||||||
|
extern struct serverstruct *servers;
|
||||||
|
extern struct connstruct *usedconns;
|
||||||
|
extern struct connstruct *freeconns;
|
||||||
|
extern struct cgiextstruct *cgiexts;
|
||||||
|
extern struct indexstruct *indexlist;
|
||||||
|
|
||||||
|
// Conf global prototypes
|
||||||
|
extern char *webroot;
|
||||||
|
extern int allowdirectorylisting;
|
||||||
|
extern int allowcgi;
|
||||||
|
extern int permcheck;
|
||||||
|
|
||||||
|
// conn.c prototypes
|
||||||
|
void addconnection(int sd, char *ip, int is_ssl);
|
||||||
|
void removeconnection(struct connstruct *cn);
|
||||||
|
|
||||||
|
// proc.c prototypes
|
||||||
|
int procheadelem(struct connstruct *cn, char *buf);
|
||||||
|
void procdirlisting(struct connstruct *cn);
|
||||||
|
void procdodir(struct connstruct *cn);
|
||||||
|
void procreadhead(struct connstruct *cn);
|
||||||
|
void procsendhead(struct connstruct *cn);
|
||||||
|
void procreadfile(struct connstruct *cn);
|
||||||
|
void procsendfile(struct connstruct *cn);
|
||||||
|
int special_write(struct connstruct *cn, const uint8_t *buf, size_t count);
|
||||||
|
|
||||||
|
// net.c prototypes
|
||||||
|
void addtoservers(int sd);
|
||||||
|
void selectloop(void);
|
||||||
|
|
||||||
|
// socket.c prototypes
|
||||||
|
void handlenewconnection(int listenfd, int is_ssl);
|
||||||
|
int openlistener(int port);
|
||||||
|
int openlistener6(int port);
|
||||||
|
|
||||||
|
// misc.c prototypes
|
||||||
|
void nada(int sigtype);
|
||||||
|
void die(int sigtype);
|
||||||
|
void reaper(int sigtype);
|
||||||
|
void stripcrlf(char *p);
|
||||||
|
char *my_strncpy(char *dest, const char *src, size_t n);
|
||||||
|
#ifndef __HAVE_ARCH_STRNLEN
|
||||||
|
size_t strnlen ( const char * str, size_t maxlen );
|
||||||
|
#endif
|
||||||
|
int iscgi(char *fn);
|
||||||
|
void split(char *tp, char *sp[], int maxwords, char sc);
|
||||||
|
int sanitizefile(char *buf);
|
||||||
|
int sanitizehost(char *buf);
|
||||||
|
void buildactualfile(struct connstruct *cn);
|
||||||
|
int issockwriteable(int sd);
|
||||||
|
int isdir(char *name);
|
||||||
|
int trycgi_withpathinfo(struct connstruct *cn);
|
||||||
|
|
||||||
|
// mime_types.c prototypes
|
||||||
|
void mime_init(void);
|
||||||
|
const char *getmimetype(const char *fn);
|
||||||
|
|
||||||
|
// main.c prototypes
|
||||||
|
void initlists(void);
|
121
httpd/conn.c
Normal file
121
httpd/conn.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
void addconnection(int sd, char *ip, int is_ssl)
|
||||||
|
{
|
||||||
|
struct connstruct *tp;
|
||||||
|
|
||||||
|
// Get ourselves a connstruct
|
||||||
|
if (freeconns == NULL)
|
||||||
|
{
|
||||||
|
tp = (struct connstruct *) malloc(sizeof(struct connstruct));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tp = freeconns;
|
||||||
|
freeconns = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach it to the used list
|
||||||
|
tp->next = usedconns;
|
||||||
|
usedconns = tp;
|
||||||
|
|
||||||
|
tp->networkdesc = sd;
|
||||||
|
if (is_ssl)
|
||||||
|
ssl_server_new(servers->ssl_ctx, sd);
|
||||||
|
tp->filedesc = -1;
|
||||||
|
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
||||||
|
tp->dirp = NULL;
|
||||||
|
#endif
|
||||||
|
tp->is_ssl = is_ssl;
|
||||||
|
|
||||||
|
*(tp->actualfile) = '\0';
|
||||||
|
*(tp->filereq) = '\0';
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
*(tp->cgiargs) = '\0';
|
||||||
|
#endif
|
||||||
|
*(tp->virtualhostreq) = '\0';
|
||||||
|
|
||||||
|
tp->state = STATE_WANT_TO_READ_HEAD;
|
||||||
|
tp->reqtype = TYPE_GET;
|
||||||
|
my_strncpy(tp->ip, ip, MAXIPLEN);
|
||||||
|
tp->close_when_done = 0;
|
||||||
|
tp->modified_since = 0;
|
||||||
|
tp->timeout = time(NULL) + CONFIG_HTTP_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeconnection(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
struct connstruct *tp;
|
||||||
|
int shouldret=0;
|
||||||
|
|
||||||
|
tp = usedconns;
|
||||||
|
|
||||||
|
if (tp == NULL || cn == NULL)
|
||||||
|
shouldret=1;
|
||||||
|
else if (tp == cn)
|
||||||
|
usedconns = tp->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(tp != NULL)
|
||||||
|
{
|
||||||
|
if (tp->next == cn)
|
||||||
|
{
|
||||||
|
tp->next = (tp->next)->next;
|
||||||
|
shouldret=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
shouldret=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If we did, add it to the free list
|
||||||
|
cn->next = freeconns;
|
||||||
|
freeconns = cn;
|
||||||
|
|
||||||
|
// Close it all down
|
||||||
|
if (cn->networkdesc != -1)
|
||||||
|
{
|
||||||
|
if (cn->is_ssl)
|
||||||
|
{
|
||||||
|
ssl_free(ssl_find(servers->ssl_ctx, cn->networkdesc));
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET_CLOSE(cn->networkdesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cn->filedesc != -1) close(cn->filedesc);
|
||||||
|
#if defined(CONFIG_HTTP_HAS_DIRECTORIES)
|
||||||
|
if (cn->dirp != NULL)
|
||||||
|
#ifdef WIN32
|
||||||
|
FindClose(cn->dirp);
|
||||||
|
#else
|
||||||
|
closedir(cn->dirp);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
323
httpd/main.c
Normal file
323
httpd/main.c
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
// GLOBALS
|
||||||
|
struct serverstruct *servers;
|
||||||
|
struct connstruct *usedconns;
|
||||||
|
struct connstruct *freeconns;
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
struct cgiextstruct *cgiexts;
|
||||||
|
#endif
|
||||||
|
struct indexstruct *indexlist;
|
||||||
|
|
||||||
|
char *webroot = CONFIG_HTTP_WEBROOT;
|
||||||
|
static void addindex(char *tp);
|
||||||
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
|
static void procpermcheck(char *pathtocheck);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
static void addcgiext(char *tp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clean up memory for valgrind */
|
||||||
|
static void sigint_cleanup(int sig)
|
||||||
|
{
|
||||||
|
struct serverstruct *sp;
|
||||||
|
struct connstruct *tp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while(servers != NULL)
|
||||||
|
{
|
||||||
|
if (servers->is_ssl)
|
||||||
|
ssl_ctx_free(servers->ssl_ctx);
|
||||||
|
|
||||||
|
sp = servers->next;
|
||||||
|
free(servers);
|
||||||
|
servers = sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(indexlist->name);
|
||||||
|
free(indexlist);
|
||||||
|
|
||||||
|
for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++)
|
||||||
|
{
|
||||||
|
if (freeconns == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
tp = freeconns->next;
|
||||||
|
free(freeconns);
|
||||||
|
freeconns = tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initlists()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct connstruct *tp;
|
||||||
|
|
||||||
|
servers = NULL;
|
||||||
|
usedconns = NULL;
|
||||||
|
freeconns = NULL;
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
cgiexts = NULL;
|
||||||
|
#endif
|
||||||
|
indexlist = NULL;
|
||||||
|
|
||||||
|
for (i=0; i<INITIAL_CONNECTION_SLOTS; i++)
|
||||||
|
{
|
||||||
|
tp = freeconns;
|
||||||
|
freeconns = (struct connstruct *) calloc(1, sizeof(struct connstruct));
|
||||||
|
freeconns->next = tp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int tp;
|
||||||
|
#if defined(CONFIG_HTTP_IS_DAEMON)
|
||||||
|
int pid;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WORD wVersionRequested = MAKEWORD(2,2);
|
||||||
|
WSADATA wsaData;
|
||||||
|
WSAStartup(wVersionRequested,&wsaData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mime_init();
|
||||||
|
initlists();
|
||||||
|
tp = strlen(webroot);
|
||||||
|
|
||||||
|
if (webroot[tp-1] == '/')
|
||||||
|
webroot[tp-1] = '\0';
|
||||||
|
|
||||||
|
if (isdir(webroot) == 0)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
fprintf(stderr, "'%s' is not a directory\n", webroot);
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tp=openlistener(CONFIG_HTTP_PORT)) == -1)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
fprintf(stderr, "ERR: Couldn't bind to port %d (IPv4)\n",
|
||||||
|
CONFIG_HTTP_PORT);
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
addindex("index.html");
|
||||||
|
addtoservers(tp);
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
if (getuid() == 0)
|
||||||
|
{
|
||||||
|
setgid(32767);
|
||||||
|
setuid(32767);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((tp=openlistener(CONFIG_HTTP_HTTPS_PORT)) == -1)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
fprintf(stderr, "ERR: Couldn't bind to port %d (IPv4)\n",
|
||||||
|
CONFIG_HTTP_HTTPS_PORT);
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
addtoservers(tp);
|
||||||
|
servers->ssl_ctx = ssl_ctx_new(CONFIG_HTTP_DEFAULT_SSL_OPTIONS,
|
||||||
|
CONFIG_HTTP_SESSION_CACHE_SIZE);
|
||||||
|
servers->is_ssl = 1;
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
|
procpermcheck(webroot);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
addcgiext(CONFIG_HTTP_CGI_EXTENSION);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_HTTP_VERBOSE)
|
||||||
|
printf("axhttpd: listening on ports http:%d and https:%d\n",
|
||||||
|
CONFIG_HTTP_PORT, CONFIG_HTTP_HTTPS_PORT);
|
||||||
|
TTY_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_IS_DAEMON)
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
if (pid > 0)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if(pid == -1)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
fprintf(stderr,"axhttpd: Sorry, fork failed... Tough dice.\n");
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setsid();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SIGNALS */
|
||||||
|
signal(SIGINT, sigint_cleanup);
|
||||||
|
signal(SIGTERM, die);
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
#ifndef WIN32
|
||||||
|
signal(SIGCHLD, reaper);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef WIN32
|
||||||
|
signal(SIGQUIT, die);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
selectloop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addindex(char *tp)
|
||||||
|
{
|
||||||
|
struct indexstruct *ex = (struct indexstruct *)
|
||||||
|
malloc(sizeof(struct indexstruct));
|
||||||
|
ex->name = strdup(tp);
|
||||||
|
ex->next = indexlist;
|
||||||
|
indexlist = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_PERM_CHECK)
|
||||||
|
static void procpermcheck(char *pathtocheck)
|
||||||
|
{
|
||||||
|
char thepath[MAXREQUESTLENGTH];
|
||||||
|
#ifndef WIN32
|
||||||
|
DIR *tpdir;
|
||||||
|
struct dirent *dp;
|
||||||
|
|
||||||
|
tpdir = opendir(pathtocheck);
|
||||||
|
|
||||||
|
if (tpdir == NULL)
|
||||||
|
{
|
||||||
|
printf("WARNING: UID (%d) is unable to read %s\n",
|
||||||
|
(int)getuid(), pathtocheck);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((dp=readdir(tpdir)))
|
||||||
|
{
|
||||||
|
if (strcmp(dp->d_name, "..")==0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(dp->d_name, ".")==0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(thepath, sizeof(thepath), "%s/%s", pathtocheck, dp->d_name);
|
||||||
|
|
||||||
|
if (isdir(thepath))
|
||||||
|
{
|
||||||
|
procpermcheck(thepath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access(thepath, R_OK) != 0)
|
||||||
|
printf("WARNING: UID (%d) is unable to read %s\n",
|
||||||
|
(int)getuid(), thepath);
|
||||||
|
if (access(thepath, W_OK) == 0)
|
||||||
|
printf("SECURITY: UID (%d) is ABLE TO WRITE TO %s\n",
|
||||||
|
(int)getuid(), thepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(tpdir);
|
||||||
|
#else /* Win32 */
|
||||||
|
HANDLE tpdir;
|
||||||
|
WIN32_FIND_DATA file_data;
|
||||||
|
struct stat st;
|
||||||
|
char buf2[1024];
|
||||||
|
|
||||||
|
strcpy(buf2, pathtocheck);
|
||||||
|
strcat(buf2, "\\*");
|
||||||
|
tpdir = FindFirstFile(buf2, &file_data);
|
||||||
|
|
||||||
|
if (tpdir == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
printf("WARNING: unable to read %s\n", buf2);
|
||||||
|
TTY_FLUSH();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (FindNextFile(tpdir, &file_data))
|
||||||
|
{
|
||||||
|
if (strcmp(file_data.cFileName, "..") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(file_data.cFileName, ".") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(thepath, sizeof(thepath), "%s\\%s",
|
||||||
|
pathtocheck, file_data.cFileName);
|
||||||
|
|
||||||
|
if (isdir(thepath))
|
||||||
|
{
|
||||||
|
procpermcheck(thepath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(thepath, &st) >= 0)
|
||||||
|
{
|
||||||
|
if ((st.st_mode & _S_IREAD) == 0)
|
||||||
|
{
|
||||||
|
printf("WARNING: unable to read %s\n", thepath);
|
||||||
|
TTY_FLUSH();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st.st_mode & _S_IWRITE)
|
||||||
|
{
|
||||||
|
printf("SECURITY: ABLE TO WRITE TO %s\n", thepath);
|
||||||
|
TTY_FLUSH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FindClose(tpdir);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_HTTP_PERM_CHECK */
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
static void addcgiext(char *tp)
|
||||||
|
{
|
||||||
|
struct cgiextstruct *ex = (struct cgiextstruct *)
|
||||||
|
malloc(sizeof(struct cgiextstruct));
|
||||||
|
ex->ext = strdup(tp);
|
||||||
|
ex->next = cgiexts;
|
||||||
|
cgiexts = ex;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
190
httpd/mime_types.c
Normal file
190
httpd/mime_types.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "os_port.h"
|
||||||
|
|
||||||
|
static const char mime_default[] = "text/plain";
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char * const ext;
|
||||||
|
const char * const type;
|
||||||
|
} mime_table_t;
|
||||||
|
|
||||||
|
static mime_table_t mime_table[] =
|
||||||
|
{
|
||||||
|
// Fundamentals
|
||||||
|
{ ".html", "text/html" },
|
||||||
|
{ ".htm", "text/html" },
|
||||||
|
{ ".txt", "text/plain" },
|
||||||
|
|
||||||
|
// Others
|
||||||
|
{ ".rtx", "text/richtext" },
|
||||||
|
{ ".etx", "text/x-setext" },
|
||||||
|
{ ".tsv", "text/tab-separated-values" },
|
||||||
|
{ ".css", "text/css" },
|
||||||
|
{ ".xml", "text/xml" },
|
||||||
|
{ ".dtd", "text/xml" },
|
||||||
|
{ ".gif", "image/gif" },
|
||||||
|
{ ".jpg", "image/jpeg" },
|
||||||
|
{ ".jpeg", "image/jpeg" },
|
||||||
|
{ ".jpe", "image/jpeg" },
|
||||||
|
{ ".jfif", "image/jpeg" },
|
||||||
|
{ ".tif", "image/tiff" },
|
||||||
|
{ ".tiff", "image/tiff" },
|
||||||
|
{ ".pbm", "image/x-portable-bitmap" },
|
||||||
|
{ ".pgm", "image/x-portable-graymap" },
|
||||||
|
{ ".ppm", "image/x-portable-pixmap" },
|
||||||
|
{ ".pnm", "image/x-portable-anymap" },
|
||||||
|
{ ".xbm", "image/x-xbitmap" },
|
||||||
|
{ ".xpm", "image/x-xpixmap" },
|
||||||
|
{ ".xwd", "image/x-xwindowdump" },
|
||||||
|
{ ".ief", "image/ief" },
|
||||||
|
{ ".png", "image/png" },
|
||||||
|
{ ".au", "audio/basic" },
|
||||||
|
{ ".snd", "audio/basic" },
|
||||||
|
{ ".aif", "audio/x-aiff" },
|
||||||
|
{ ".aiff", "audio/x-aiff" },
|
||||||
|
{ ".aifc", "audio/x-aiff" },
|
||||||
|
{ ".ra", "audio/x-pn-realaudio" },
|
||||||
|
{ ".ram", "audio/x-pn-realaudio" },
|
||||||
|
{ ".rm", "audio/x-pn-realaudio" },
|
||||||
|
{ ".rpm", "audio/x-pn-realaudio-plugin" },
|
||||||
|
{ ".wav", "audio/wav" },
|
||||||
|
{ ".mid", "audio/midi" },
|
||||||
|
{ ".midi", "audio/midi" },
|
||||||
|
{ ".kar", "audio/midi" },
|
||||||
|
{ ".mpga", "audio/mpeg" },
|
||||||
|
{ ".mp2", "audio/mpeg" },
|
||||||
|
{ ".mp3", "audio/mpeg" },
|
||||||
|
{ ".mpeg", "video/mpeg" },
|
||||||
|
{ ".mpg", "video/mpeg" },
|
||||||
|
{ ".mpe", "video/mpeg" },
|
||||||
|
{ ".qt", "video/quicktime" },
|
||||||
|
{ ".mov", "video/quicktime" },
|
||||||
|
{ ".avi", "video/x-msvideo" },
|
||||||
|
{ ".movie", "video/x-sgi-movie" },
|
||||||
|
{ ".mv", "video/x-sgi-movie" },
|
||||||
|
{ ".vx", "video/x-rad-screenplay" },
|
||||||
|
{ ".a", "application/octet-stream" },
|
||||||
|
{ ".bin", "application/octet-stream" },
|
||||||
|
{ ".exe", "application/octet-stream" },
|
||||||
|
{ ".dump", "application/octet-stream" },
|
||||||
|
{ ".o", "application/octet-stream" },
|
||||||
|
{ ".class", "application/java" },
|
||||||
|
{ ".js", "application/x-javascript" },
|
||||||
|
{ ".ai", "application/postscript" },
|
||||||
|
{ ".eps", "application/postscript" },
|
||||||
|
{ ".ps", "application/postscript" },
|
||||||
|
{ ".dir", "application/x-director" },
|
||||||
|
{ ".dcr", "application/x-director" },
|
||||||
|
{ ".dxr", "application/x-director" },
|
||||||
|
{ ".fgd", "application/x-director" },
|
||||||
|
{ ".aam", "application/x-authorware-map" },
|
||||||
|
{ ".aas", "application/x-authorware-seg" },
|
||||||
|
{ ".aab", "application/x-authorware-bin" },
|
||||||
|
{ ".fh4", "image/x-freehand" },
|
||||||
|
{ ".fh7", "image/x-freehand" },
|
||||||
|
{ ".fh5", "image/x-freehand" },
|
||||||
|
{ ".fhc", "image/x-freehand" },
|
||||||
|
{ ".fh", "image/x-freehand" },
|
||||||
|
{ ".spl", "application/futuresplash" },
|
||||||
|
{ ".swf", "application/x-shockwave-flash" },
|
||||||
|
{ ".dvi", "application/x-dvi" },
|
||||||
|
{ ".gtar", "application/x-gtar" },
|
||||||
|
{ ".hdf", "application/x-hdf" },
|
||||||
|
{ ".hqx", "application/mac-binhex40" },
|
||||||
|
{ ".iv", "application/x-inventor" },
|
||||||
|
{ ".latex", "application/x-latex" },
|
||||||
|
{ ".man", "application/x-troff-man" },
|
||||||
|
{ ".me", "application/x-troff-me" },
|
||||||
|
{ ".mif", "application/x-mif" },
|
||||||
|
{ ".ms", "application/x-troff-ms" },
|
||||||
|
{ ".oda", "application/oda" },
|
||||||
|
{ ".pdf", "application/pdf" },
|
||||||
|
{ ".rtf", "application/rtf" },
|
||||||
|
{ ".bcpio", "application/x-bcpio" },
|
||||||
|
{ ".cpio", "application/x-cpio" },
|
||||||
|
{ ".sv4cpio", "application/x-sv4cpio" },
|
||||||
|
{ ".sv4crc", "application/x-sv4crc" },
|
||||||
|
{ ".sh", "application/x-shar" },
|
||||||
|
{ ".shar", "application/x-shar" },
|
||||||
|
{ ".sit", "application/x-stuffit" },
|
||||||
|
{ ".tar", "application/x-tar" },
|
||||||
|
{ ".tex", "application/x-tex" },
|
||||||
|
{ ".texi", "application/x-texinfo" },
|
||||||
|
{ ".texinfo", "application/x-texinfo" },
|
||||||
|
{ ".tr", "application/x-troff" },
|
||||||
|
{ ".roff", "application/x-troff" },
|
||||||
|
{ ".man", "application/x-troff-man" },
|
||||||
|
{ ".me", "application/x-troff-me" },
|
||||||
|
{ ".ms", "application/x-troff-ms" },
|
||||||
|
{ ".zip", "application/x-zip-compressed" },
|
||||||
|
{ ".tsp", "application/dsptype" },
|
||||||
|
{ ".wsrc", "application/x-wais-source" },
|
||||||
|
{ ".ustar", "application/x-ustar" },
|
||||||
|
{ ".cdf", "application/x-netcdf" },
|
||||||
|
{ ".nc", "application/x-netcdf" },
|
||||||
|
{ ".doc", "application/msword" },
|
||||||
|
{ ".ppt", "application/powerpoint" },
|
||||||
|
{ ".wrl", "model/vrml" },
|
||||||
|
{ ".vrml", "model/vrml" },
|
||||||
|
{ ".mime", "message/rfc822" },
|
||||||
|
{ ".pac", "application/x-ns-proxy-autoconfig" },
|
||||||
|
{ ".wml", "text/vnd.wap.wml" },
|
||||||
|
{ ".wmlc", "application/vnd.wap.wmlc" },
|
||||||
|
{ ".wmls", "text/vnd.wap.wmlscript" },
|
||||||
|
{ ".wmlsc", "application/vnd.wap.wmlscriptc" },
|
||||||
|
{ ".wbmp", "image/vnd.wap.wbmp" },
|
||||||
|
{ ".tgz", "application/x-gzip" },
|
||||||
|
{ ".tar.gz", "application/x-gzip" },
|
||||||
|
{ ".bz2", "application/x-bzip2" },
|
||||||
|
{ ".zip", "application/zip" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mime_cmp(const mime_table_t *t1, const mime_table_t *t2)
|
||||||
|
{
|
||||||
|
return strcasecmp(t1->ext, t2->ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mime_init(void)
|
||||||
|
{
|
||||||
|
qsort(mime_table, sizeof(mime_table)/sizeof(mime_table_t),
|
||||||
|
sizeof(mime_table_t),
|
||||||
|
(int (*)(const void *, const void *))mime_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getmimetype(const char *name)
|
||||||
|
{
|
||||||
|
mime_table_t *mime_type;
|
||||||
|
|
||||||
|
if ((name = strrchr(name, '.')) == NULL)
|
||||||
|
return mime_default;
|
||||||
|
|
||||||
|
mime_type = bsearch(&name, mime_table,
|
||||||
|
sizeof(mime_table)/sizeof(mime_table_t),
|
||||||
|
sizeof(mime_table_t),
|
||||||
|
(int (*)(const void *, const void *))mime_cmp);
|
||||||
|
|
||||||
|
return mime_type == NULL ? mime_default : mime_type->type;
|
||||||
|
}
|
||||||
|
|
268
httpd/misc.c
Normal file
268
httpd/misc.c
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
void nada(int sigtype) { }
|
||||||
|
|
||||||
|
void die(int sigtype)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
#ifndef WIN32
|
||||||
|
void reaper(int sigtype)
|
||||||
|
{
|
||||||
|
wait3(NULL,WNOHANG,NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void stripcrlf(char *p)
|
||||||
|
{
|
||||||
|
while (p && *p)
|
||||||
|
{
|
||||||
|
if (*p=='\n' || *p=='\r')
|
||||||
|
{
|
||||||
|
*p='\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper function for strncpy() that guarantees
|
||||||
|
a null-terminated string. This is to avoid any possible
|
||||||
|
issues due to strncpy()'s behaviour. Thanks to
|
||||||
|
Werner Almesberger for pointing out this potential
|
||||||
|
issue. Needless to say, make sure sizeof(dest) > 0
|
||||||
|
and sizeof(dest) >= n.
|
||||||
|
*/
|
||||||
|
char *my_strncpy(char *dest, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
strncpy(dest, src, n);
|
||||||
|
dest[n-1] = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strnlen is a GNU Extension */
|
||||||
|
#ifndef __HAVE_ARCH_STRNLEN
|
||||||
|
size_t strnlen (const char * str, size_t maxlen)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
for (p=str; maxlen-- && *p!='\0'; ++p);
|
||||||
|
return (p - str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int sanitizefile(char *buf)
|
||||||
|
{
|
||||||
|
int len, i;
|
||||||
|
|
||||||
|
// Don't accept anything not starting with a /
|
||||||
|
if (*buf != '/')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len = strlen(buf);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
// Check for "/." : In other words, don't send files starting with a .
|
||||||
|
// Notice, GOBBLES, that this includes ".."
|
||||||
|
if (buf[i] == '/' && buf[i+1] == '.')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sanitizehost(char *buf)
|
||||||
|
{
|
||||||
|
while(*buf != '\0')
|
||||||
|
{
|
||||||
|
// Handle the port
|
||||||
|
if (*buf == ':')
|
||||||
|
{
|
||||||
|
*buf = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce some basic URL rules...
|
||||||
|
if (isalnum(*buf)==0 && *buf != '-' && *buf != '.') return 0;
|
||||||
|
if (*buf == '.' && *(buf+1) == '.') return 0;
|
||||||
|
if (*buf == '.' && *(buf+1) == '-') return 0;
|
||||||
|
if (*buf == '-' && *(buf+1) == '.') return 0;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildactualfile(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
snprintf(cn->actualfile, MAXREQUESTLENGTH, "%s%s",
|
||||||
|
webroot,
|
||||||
|
cn->filereq);
|
||||||
|
|
||||||
|
/* Add directory slash if not there */
|
||||||
|
if (isdir(cn->actualfile) &&
|
||||||
|
cn->actualfile[strlen(cn->actualfile)-1] != '/')
|
||||||
|
strcat(cn->actualfile, "/");
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* convert all the forward slashes to back slashes */
|
||||||
|
{
|
||||||
|
char *t = cn->actualfile;
|
||||||
|
while ((t = strchr(t, '/')))
|
||||||
|
{
|
||||||
|
*t++ = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
int issockwriteable(int sd)
|
||||||
|
{
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(sd, &wfds);
|
||||||
|
|
||||||
|
select(FD_SETSIZE, NULL, &wfds, NULL, &tv);
|
||||||
|
|
||||||
|
return FD_ISSET(sd, &wfds);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int isdir(char *tpbuf)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(tpbuf, &st) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((st.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
int iscgi(char *fn)
|
||||||
|
{
|
||||||
|
struct cgiextstruct *tp;
|
||||||
|
int fnlen, extlen;
|
||||||
|
|
||||||
|
fnlen = strlen(fn);
|
||||||
|
tp = cgiexts;
|
||||||
|
|
||||||
|
while (tp != NULL)
|
||||||
|
{
|
||||||
|
extlen = strlen(tp->ext);
|
||||||
|
|
||||||
|
if (strcasecmp(fn+(fnlen-extlen), tp->ext) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void split(char *tp, char *sp[], int maxwords, char sc)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
/* Skip leading whitespace */
|
||||||
|
while(*tp == sc) tp++;
|
||||||
|
|
||||||
|
if (*tp == '\0')
|
||||||
|
{
|
||||||
|
sp[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==maxwords-2)
|
||||||
|
{
|
||||||
|
sp[maxwords-2] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp[i] = tp;
|
||||||
|
|
||||||
|
while(*tp != sc && *tp != '\0')
|
||||||
|
tp++;
|
||||||
|
|
||||||
|
if (*tp == sc)
|
||||||
|
*tp++ = '\0';
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int trycgi_withpathinfo(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char tpfile[MAXREQUESTLENGTH];
|
||||||
|
char fr_str[MAXREQUESTLENGTH];
|
||||||
|
char *fr_rs[MAXCGIARGS]; // filereq splitted
|
||||||
|
int i = 0, offset;
|
||||||
|
|
||||||
|
my_strncpy(fr_str, cn->filereq, MAXREQUESTLENGTH);
|
||||||
|
split(fr_str, fr_rs, MAXCGIARGS, '/');
|
||||||
|
|
||||||
|
while (fr_rs[i] != NULL)
|
||||||
|
{
|
||||||
|
snprintf(tpfile, sizeof(tpfile), "%s/%s%s",
|
||||||
|
webroot, cn->virtualhostreq, fr_str);
|
||||||
|
|
||||||
|
if (iscgi(tpfile) && isdir(tpfile) == 0)
|
||||||
|
{
|
||||||
|
/* We've found our CGI file! */
|
||||||
|
my_strncpy(cn->actualfile, tpfile, MAXREQUESTLENGTH);
|
||||||
|
my_strncpy(cn->cgiscriptinfo, fr_str, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
|
offset = (fr_rs[i] + strlen(fr_rs[i])) - fr_str;
|
||||||
|
my_strncpy(cn->cgipathinfo, cn->filereq+offset, MAXREQUESTLENGTH);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(fr_rs[i]+strlen(fr_rs[i])) = '/';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Couldn't find any CGIs :( */
|
||||||
|
*(cn->cgiscriptinfo) = '\0';
|
||||||
|
*(cn->cgipathinfo) = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
176
httpd/net.c
Normal file
176
httpd/net.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
void addtoservers(int sd)
|
||||||
|
{
|
||||||
|
struct serverstruct *tp = (struct serverstruct *)
|
||||||
|
calloc(1, sizeof(struct serverstruct));
|
||||||
|
tp->next = servers;
|
||||||
|
tp->sd = sd;
|
||||||
|
servers = tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectloop()
|
||||||
|
{
|
||||||
|
fd_set rfds, wfds;
|
||||||
|
struct connstruct *tp, *to;
|
||||||
|
struct serverstruct *sp;
|
||||||
|
int rnum, wnum, active;
|
||||||
|
int currtime;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// MAIN SELECT LOOP
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
rnum = wnum = -1;
|
||||||
|
|
||||||
|
// Add the listening sockets
|
||||||
|
sp = servers;
|
||||||
|
while (sp != NULL)
|
||||||
|
{
|
||||||
|
FD_SET(sp->sd, &rfds);
|
||||||
|
if (sp->sd > rnum) rnum = sp->sd;
|
||||||
|
sp = sp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the established sockets
|
||||||
|
tp = usedconns;
|
||||||
|
currtime = time(NULL);
|
||||||
|
|
||||||
|
while (tp != NULL)
|
||||||
|
{
|
||||||
|
if (currtime > tp->timeout)
|
||||||
|
{
|
||||||
|
to = tp;
|
||||||
|
tp = tp->next;
|
||||||
|
removeconnection(to);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_READ_HEAD)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &rfds);
|
||||||
|
if (tp->networkdesc > rnum)
|
||||||
|
rnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_SEND_HEAD)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_READ_FILE)
|
||||||
|
{
|
||||||
|
FD_SET(tp->filedesc, &rfds);
|
||||||
|
if (tp->filedesc > rnum)
|
||||||
|
rnum = tp->filedesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->state == STATE_WANT_TO_SEND_FILE)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
if (tp->state == STATE_DOING_DIR)
|
||||||
|
{
|
||||||
|
FD_SET(tp->networkdesc, &wfds);
|
||||||
|
if (tp->networkdesc > wnum)
|
||||||
|
wnum = tp->networkdesc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
active = select(wnum > rnum ? wnum+1 : rnum+1,
|
||||||
|
rnum != -1 ? &rfds : NULL,
|
||||||
|
wnum != -1 ? &wfds : NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
// Handle the listening sockets
|
||||||
|
sp = servers;
|
||||||
|
while (active > 0 && sp != NULL)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(sp->sd, &rfds))
|
||||||
|
{
|
||||||
|
handlenewconnection(sp->sd, sp->is_ssl);
|
||||||
|
active--;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = sp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the established sockets
|
||||||
|
tp = usedconns;
|
||||||
|
|
||||||
|
while (active > 0 && tp != NULL)
|
||||||
|
{
|
||||||
|
to = tp;
|
||||||
|
tp = tp->next;
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_READ_HEAD)
|
||||||
|
if (FD_ISSET(to->networkdesc, &rfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procreadhead(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_SEND_HEAD)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procsendhead(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_READ_FILE)
|
||||||
|
if (FD_ISSET(to->filedesc, &rfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procreadfile(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to->state == STATE_WANT_TO_SEND_FILE)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procsendfile(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
if (to->state == STATE_DOING_DIR)
|
||||||
|
if (FD_ISSET(to->networkdesc, &wfds))
|
||||||
|
{
|
||||||
|
active--;
|
||||||
|
procdodir(to);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // MAIN SELECT LOOP
|
||||||
|
}
|
780
httpd/proc.c
Normal file
780
httpd/proc.c
Normal file
@ -0,0 +1,780 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
static int special_read(struct connstruct *cn, void *buf, size_t count);
|
||||||
|
static void send301(struct connstruct *cn);
|
||||||
|
static void send404(struct connstruct *cn);
|
||||||
|
static int procindex(struct connstruct *cn, struct stat *stp);
|
||||||
|
static int hexit(char c);
|
||||||
|
static void urlencode(unsigned char *s, unsigned char *t);
|
||||||
|
static void urldecode(char *buf);
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
static void proccgi(struct connstruct *cn, int has_pathinfo);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Returns 1 if elems should continue being read, 0 otherwise
|
||||||
|
int procheadelem(struct connstruct *cn, char *buf)
|
||||||
|
{
|
||||||
|
char *delim, *value;
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
char *cgi_delim;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((delim = strchr(buf, ' ')) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*delim = 0;
|
||||||
|
value = delim+1;
|
||||||
|
|
||||||
|
if (strcmp(buf, "GET")==0 ||
|
||||||
|
strcmp(buf, "HEAD")==0 ||
|
||||||
|
strcmp(buf, "POST")==0)
|
||||||
|
{
|
||||||
|
if (buf[0] == 'H')
|
||||||
|
cn->reqtype = TYPE_HEAD;
|
||||||
|
else if (buf[0] == 'P')
|
||||||
|
cn->reqtype = TYPE_POST;
|
||||||
|
|
||||||
|
if ((delim = strchr(value, ' ')) == NULL) /* expect HTTP type */
|
||||||
|
return 0;
|
||||||
|
*delim = 0;
|
||||||
|
|
||||||
|
urldecode(value);
|
||||||
|
|
||||||
|
if (sanitizefile(value) == 0)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_strncpy(cn->filereq, value, MAXREQUESTLENGTH);
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
if ((cgi_delim = strchr(value, '?')))
|
||||||
|
{
|
||||||
|
*cgi_delim = 0;
|
||||||
|
my_strncpy(cn->cgiargs, value+1, MAXREQUESTLENGTH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (strcmp(buf, "Host:")==0)
|
||||||
|
{
|
||||||
|
if (sanitizehost(value) == 0)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_strncpy(cn->virtualhostreq, value, MAXREQUESTLENGTH);
|
||||||
|
}
|
||||||
|
else if (strcmp(buf, "Connection:")==0 &&
|
||||||
|
strcmp(value, "close")==0) {
|
||||||
|
cn->close_when_done = 1;
|
||||||
|
}
|
||||||
|
else if (strcmp(buf, "If-Modified-Since:") ==0 )
|
||||||
|
{
|
||||||
|
/* TODO: parse this date properly with getdate() or similar */
|
||||||
|
cn->modified_since = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
void procdirlisting(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[MAXREQUESTLENGTH];
|
||||||
|
char actualfile[1024];
|
||||||
|
|
||||||
|
#ifndef CONFIG_HTTP_DIRECTORIES
|
||||||
|
if (allowdirectorylisting == 0)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cn->reqtype == TYPE_HEAD)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nContent-Type: text/html\n\n");
|
||||||
|
write(cn->networkdesc, buf, strlen(buf));
|
||||||
|
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(actualfile, cn->actualfile);
|
||||||
|
#ifdef WIN32
|
||||||
|
strcat(actualfile, "*");
|
||||||
|
cn->dirp = FindFirstFile(actualfile, &cn->file_data);
|
||||||
|
if (cn->dirp == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
cn->dirp = opendir(actualfile);
|
||||||
|
|
||||||
|
if (cn->dirp == NULL)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of the "."
|
||||||
|
readdir(cn->dirp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sprintf(buf, "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<HTML><BODY>\n<TITLE>Directory Listing</TITLE>\n<H2>Directory listing of %s://%s%s</H2><BR>\n", cn->is_ssl ? "https" : "http", cn->virtualhostreq, cn->filereq);
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
cn->state = STATE_DOING_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void procdodir(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
struct dirent *dp;
|
||||||
|
#endif
|
||||||
|
char buf[MAXREQUESTLENGTH];
|
||||||
|
char encbuf[1024];
|
||||||
|
int putslash;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
if (!FindNextFile(cn->dirp, &cn->file_data))
|
||||||
|
#else
|
||||||
|
if ((dp = readdir(cn->dirp)) == NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "</BODY></HTML>\n");
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
file = cn->file_data.cFileName;
|
||||||
|
#else
|
||||||
|
file = dp->d_name;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cn->filereq[0] == '/' && cn->filereq[1] == '\0' &&
|
||||||
|
strcmp(file, "..") == 0) continue;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s%s", cn->actualfile, file);
|
||||||
|
putslash = isdir(buf);
|
||||||
|
|
||||||
|
urlencode(file, encbuf);
|
||||||
|
snprintf(buf, sizeof(buf), "<A HREF=\"%s%s\">%s%s</A><BR>\n",
|
||||||
|
encbuf, putslash ? "/" : "", file, putslash ? "/" : "");
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
|
||||||
|
}
|
||||||
|
while (issockwriteable(cn->networkdesc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void procreadhead(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[MAXREQUESTLENGTH*4], *tp, *next;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = special_read(cn, buf, sizeof(buf)-1);
|
||||||
|
if (rv <= 0) {
|
||||||
|
if (rv < 0)
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[rv] = '\0';
|
||||||
|
|
||||||
|
next = tp = buf;
|
||||||
|
|
||||||
|
// Split up lines and send to procheadelem()
|
||||||
|
while(*next != '\0')
|
||||||
|
{
|
||||||
|
// If we have a blank line, advance to next stage!
|
||||||
|
if (*next == '\r' || *next == '\n')
|
||||||
|
{
|
||||||
|
buildactualfile(cn);
|
||||||
|
|
||||||
|
cn->state = STATE_WANT_TO_SEND_HEAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*next != '\r' && *next != '\n' && *next != '\0')
|
||||||
|
next++;
|
||||||
|
|
||||||
|
if (*next == '\r')
|
||||||
|
{
|
||||||
|
*next = '\0';
|
||||||
|
next+=2;
|
||||||
|
}
|
||||||
|
else if (*next == '\n')
|
||||||
|
*next++ = '\0';
|
||||||
|
|
||||||
|
if (procheadelem(cn, tp) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tp = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In this function we assume that the file has been checked for
|
||||||
|
* maliciousness (".."s, etc) and has been decoded
|
||||||
|
*/
|
||||||
|
void procsendhead(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
char actualfile[1024];
|
||||||
|
struct stat stbuf;
|
||||||
|
time_t now = cn->timeout - CONFIG_HTTP_TIMEOUT;
|
||||||
|
char date[32];
|
||||||
|
strcpy(date, ctime(&now));
|
||||||
|
|
||||||
|
strcpy(actualfile, cn->actualfile);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* stat() under win32 can't deal with trail slash */
|
||||||
|
if (actualfile[strlen(actualfile)-1] == '\\')
|
||||||
|
actualfile[strlen(actualfile)-1] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (stat(actualfile, &stbuf) == -1)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
if (trycgi_withpathinfo(cn) == 0)
|
||||||
|
{ // We Try To Find A CGI
|
||||||
|
proccgi(cn,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
if (iscgi(cn->actualfile))
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
// Set up CGI script
|
||||||
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
proccgi(cn,0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
{
|
||||||
|
if (cn->filereq[strlen(cn->filereq)-1] != '/')
|
||||||
|
{
|
||||||
|
send301(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if this dir has an index file
|
||||||
|
if (procindex(cn, &stbuf) == 0)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
// If not, we do a directory listing of it
|
||||||
|
procdirlisting(cn);
|
||||||
|
#else
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
// If the index is a CGI file, handle it like any other CGI
|
||||||
|
if (iscgi(cn->actualfile))
|
||||||
|
{
|
||||||
|
// Set up CGI script
|
||||||
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proccgi(cn,0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// If the index isn't a CGI, we continue on with the index file
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
|
||||||
|
{
|
||||||
|
if (cn->filereq[strlen(cn->filereq)-1] != '/')
|
||||||
|
{
|
||||||
|
send301(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if this dir has an index file
|
||||||
|
if (procindex(cn, &stbuf) == 0)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_HTTP_DIRECTORIES)
|
||||||
|
// If not, we do a directory listing of it
|
||||||
|
procdirlisting(cn);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
// If the index is a CGI file, handle it like any other CGI
|
||||||
|
if (iscgi(cn->actualfile))
|
||||||
|
{
|
||||||
|
// Set up CGI script
|
||||||
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proccgi(cn,0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// If the index isn't a CGI, we continue on with the index file
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cn->modified_since)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "HTTP/1.1 304 Not Modified\nServer: axhttpd V%s\nDate: %s\n", VERSION, date);
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
cn->modified_since = 0;
|
||||||
|
cn->state = STATE_WANT_TO_READ_HEAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HTTP_VERBOSE
|
||||||
|
printf("axhttpd: %s send %s\n",
|
||||||
|
cn->is_ssl ? "https" : "http", cn->actualfile);
|
||||||
|
TTY_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\nContent-Type: %s\nContent-Length: %ld\nDate: %sLast-Modified: %s\n",
|
||||||
|
VERSION,
|
||||||
|
getmimetype(cn->actualfile),
|
||||||
|
(long) stbuf.st_size,
|
||||||
|
date,
|
||||||
|
ctime(&(stbuf.st_mtime))); // ctime() has a \n on the end
|
||||||
|
}
|
||||||
|
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
|
||||||
|
if (cn->reqtype == TYPE_HEAD)
|
||||||
|
{
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int flags = O_RDONLY;
|
||||||
|
#if defined(WIN32) || defined(CYGWIN)
|
||||||
|
flags |= O_BINARY;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cn->filedesc = open(cn->actualfile, flags);
|
||||||
|
if (cn->filedesc == -1)
|
||||||
|
{
|
||||||
|
send404(cn);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
procreadfile(cn);
|
||||||
|
if (cn->filedesc == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
procsendfile(cn);
|
||||||
|
} while (cn->state != STATE_WANT_TO_READ_FILE);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void procreadfile(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
int rv = read(cn->filedesc, cn->databuf, BLOCKSIZE);
|
||||||
|
|
||||||
|
if (rv == 0 || rv == -1)
|
||||||
|
{
|
||||||
|
close(cn->filedesc);
|
||||||
|
cn->filedesc = -1;
|
||||||
|
if (cn->close_when_done) /* close immediately */
|
||||||
|
removeconnection(cn);
|
||||||
|
else
|
||||||
|
{ /* keep socket open - HTTP 1.1 */
|
||||||
|
cn->state = STATE_WANT_TO_READ_HEAD;
|
||||||
|
cn->numbytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cn->numbytes = rv;
|
||||||
|
cn->state = STATE_WANT_TO_SEND_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void procsendfile(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
int rv = special_write(cn, cn->databuf, cn->numbytes);
|
||||||
|
|
||||||
|
if (rv < 0)
|
||||||
|
removeconnection(cn);
|
||||||
|
else if (rv == cn->numbytes)
|
||||||
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
else if (rv == 0)
|
||||||
|
{ /* Do nothing */ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memmove(cn->databuf, cn->databuf + rv, cn->numbytes - rv);
|
||||||
|
cn->numbytes -= rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int special_write(struct connstruct *cn, const uint8_t *buf, size_t count)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (cn->is_ssl)
|
||||||
|
{
|
||||||
|
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
res = ssl_write(ssl, (unsigned char *)buf, count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = SOCKET_WRITE(cn->networkdesc, buf, count);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int special_read(struct connstruct *cn, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (cn->is_ssl)
|
||||||
|
{
|
||||||
|
SSL *ssl = ssl_find(servers->ssl_ctx, cn->networkdesc);
|
||||||
|
unsigned char *read_buf;
|
||||||
|
|
||||||
|
if ((res = ssl_read(ssl, &read_buf)) > SSL_OK)
|
||||||
|
memcpy(buf, read_buf, res > (int)count ? count : res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = SOCKET_READ(cn->networkdesc, buf, count);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send301(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[2048];
|
||||||
|
sprintf(buf, "HTTP/1.1 301 Moved Permanently\nLocation: %s/\n\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<HTML><HEAD>\n<TITLE>301 Moved Permanently</TITLE>\n</HEAD><BODY>\n<H1>Moved Permanently</H1>\nThe document has moved <A HREF=\"%s/\">here</A>.<P>\n<HR>\n</BODY></HTML>\n", cn->filereq, cn->filereq);
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send404(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
sprintf(buf, "HTTP/1.0 404 Not Found\nContent-Type: text/html\n\n<HTML><BODY>\n<TITLE>404 Not Found</TITLE><H1>It ain't there my friend. (404 Not Found)</H1>\n</BODY></HTML>\n");
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns 0 if no index was found and doesn't modify cn->actualfile
|
||||||
|
// Returns 1 if an index was found and puts the index in cn->actualfile
|
||||||
|
// and puts its stat info into stp
|
||||||
|
static int procindex(struct connstruct *cn, struct stat *stp)
|
||||||
|
{
|
||||||
|
char tbuf[MAXREQUESTLENGTH];
|
||||||
|
struct indexstruct *tp;
|
||||||
|
|
||||||
|
tp = indexlist;
|
||||||
|
|
||||||
|
while(tp != NULL) {
|
||||||
|
sprintf(tbuf, "%s%s%s", cn->actualfile,
|
||||||
|
#ifdef WIN32
|
||||||
|
"\\",
|
||||||
|
#else
|
||||||
|
"/",
|
||||||
|
#endif
|
||||||
|
tp->name);
|
||||||
|
|
||||||
|
if (stat(tbuf, stp) != -1)
|
||||||
|
{
|
||||||
|
my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
static void proccgi(struct connstruct *cn, int has_pathinfo)
|
||||||
|
{
|
||||||
|
int tpipe[2];
|
||||||
|
char *myargs[5];
|
||||||
|
char buf[MAXREQUESTLENGTH];
|
||||||
|
#ifdef WIN32
|
||||||
|
int tmp_stdout;
|
||||||
|
#else
|
||||||
|
int fv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\nServer: axhttpd V%s\n%s",
|
||||||
|
VERSION, (cn->reqtype == TYPE_HEAD) ? "\n" : "");
|
||||||
|
special_write(cn, buf, strlen(buf));
|
||||||
|
|
||||||
|
if (cn->reqtype == TYPE_HEAD)
|
||||||
|
{
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
if (pipe(tpipe) == -1)
|
||||||
|
{
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fv = fork();
|
||||||
|
|
||||||
|
if (fv == -1)
|
||||||
|
{
|
||||||
|
close(tpipe[0]);
|
||||||
|
close(tpipe[1]);
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fv != 0)
|
||||||
|
{
|
||||||
|
// Close the write descriptor
|
||||||
|
close(tpipe[1]);
|
||||||
|
cn->filedesc = tpipe[0];
|
||||||
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The problem child...
|
||||||
|
|
||||||
|
// Our stdout/stderr goes to the socket
|
||||||
|
dup2(tpipe[1], 1);
|
||||||
|
dup2(tpipe[1], 2);
|
||||||
|
|
||||||
|
// If it was a POST request, send the socket data to our stdin
|
||||||
|
if (cn->reqtype == TYPE_POST)
|
||||||
|
dup2(cn->networkdesc, 0);
|
||||||
|
else // Otherwise we can shutdown the read side of the sock
|
||||||
|
shutdown(cn->networkdesc, 0);
|
||||||
|
|
||||||
|
close(tpipe[0]);
|
||||||
|
close(tpipe[1]);
|
||||||
|
|
||||||
|
myargs[0] = cn->actualfile;
|
||||||
|
myargs[1] = cn->cgiargs;
|
||||||
|
myargs[2] = NULL;
|
||||||
|
|
||||||
|
if (!has_pathinfo)
|
||||||
|
{
|
||||||
|
my_strncpy(cn->cgipathinfo, "/", MAXREQUESTLENGTH);
|
||||||
|
my_strncpy(cn->cgiscriptinfo, cn->filereq, MAXREQUESTLENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
execv(cn->actualfile, myargs);
|
||||||
|
#else /* WIN32 */
|
||||||
|
if (_pipe(tpipe, 4096, O_BINARY| O_NOINHERIT) == -1)
|
||||||
|
{
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myargs[0] = "sh";
|
||||||
|
myargs[1] = "-c";
|
||||||
|
myargs[2] = cn->actualfile;
|
||||||
|
myargs[3] = cn->cgiargs;
|
||||||
|
myargs[4] = NULL;
|
||||||
|
|
||||||
|
/* convert all the forward slashes to back slashes */
|
||||||
|
{
|
||||||
|
char *t = myargs[2];
|
||||||
|
while ((t = strchr(t, '\\')))
|
||||||
|
{
|
||||||
|
*t++ = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_stdout = _dup(_fileno(stdout));
|
||||||
|
_dup2(tpipe[1], _fileno(stdout));
|
||||||
|
close(tpipe[1]);
|
||||||
|
|
||||||
|
/* change to suit execution method */
|
||||||
|
if (spawnl(P_NOWAIT, "c:\\Program Files\\cygwin\\bin\\sh.exe",
|
||||||
|
myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]) == -1)
|
||||||
|
{
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dup2(tmp_stdout, _fileno(stdout));
|
||||||
|
close(tmp_stdout);
|
||||||
|
cn->filedesc = tpipe[0];
|
||||||
|
cn->state = STATE_WANT_TO_READ_FILE;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
procreadfile(cn);
|
||||||
|
|
||||||
|
if (cn->filedesc == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
procsendfile(cn);
|
||||||
|
usleep(200000); /* don't know why this delay makes it work (yet) */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_HTTP_HAS_CGI */
|
||||||
|
|
||||||
|
/* Encode funny chars -> %xx in newly allocated storage */
|
||||||
|
/* (preserves '/' !) */
|
||||||
|
static void urlencode(unsigned char *s, unsigned char *t)
|
||||||
|
{
|
||||||
|
uint8_t *p, *tp;
|
||||||
|
|
||||||
|
tp =t ;
|
||||||
|
|
||||||
|
for (p=s; *p; p++)
|
||||||
|
{
|
||||||
|
if ((*p > 0x00 && *p < ',') ||
|
||||||
|
(*p > '9' && *p < 'A') ||
|
||||||
|
(*p > 'Z' && *p < '_') ||
|
||||||
|
(*p > '_' && *p < 'a') ||
|
||||||
|
(*p > 'z' && *p < 0xA1)) {
|
||||||
|
sprintf((char *)tp, "%%%02X", *p);
|
||||||
|
tp += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*tp = *p;
|
||||||
|
tp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*tp='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode string %xx -> char (in place) */
|
||||||
|
static void urldecode(char *buf)
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
char *p, *s, *w;
|
||||||
|
|
||||||
|
w = p = buf;
|
||||||
|
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
v = 0;
|
||||||
|
|
||||||
|
if (*p=='%')
|
||||||
|
{
|
||||||
|
s = p;
|
||||||
|
s++;
|
||||||
|
|
||||||
|
if (isxdigit((int) s[0]) && isxdigit((int) s[1]))
|
||||||
|
{
|
||||||
|
v = hexit(s[0])*16+hexit(s[1]);
|
||||||
|
if (v)
|
||||||
|
{ /* do not decode %00 to null char */
|
||||||
|
*w=(char)v;
|
||||||
|
p=&s[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v)
|
||||||
|
*w=*p;
|
||||||
|
p++; w++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*w='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hexit(char c)
|
||||||
|
{
|
||||||
|
if ( c >= '0' && c <= '9' )
|
||||||
|
return c - '0';
|
||||||
|
if ( c >= 'a' && c <= 'f' )
|
||||||
|
return c - 'a' + 10;
|
||||||
|
if ( c >= 'A' && c <= 'F' )
|
||||||
|
return c - 'A' + 10;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
129
httpd/socket.c
Normal file
129
httpd/socket.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright(C) 2006 Cameron Rich
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
|
||||||
|
void handlenewconnection(int listenfd, int is_ssl)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 their_addr;
|
||||||
|
int tp = sizeof(their_addr);
|
||||||
|
char ipbuf[100];
|
||||||
|
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
||||||
|
|
||||||
|
if (connfd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tp == sizeof(struct sockaddr_in6))
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET6, &their_addr.sin6_addr, ipbuf, sizeof(ipbuf));
|
||||||
|
}
|
||||||
|
else if (tp == sizeof(struct sockaddr_in))
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET, &(((struct sockaddr_in *)&their_addr)->sin_addr),
|
||||||
|
ipbuf, sizeof(ipbuf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ipbuf = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
addconnection(connfd, ipbuf, is_ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void handlenewconnection(int listenfd, int is_ssl)
|
||||||
|
{
|
||||||
|
struct sockaddr_in their_addr;
|
||||||
|
int tp = sizeof(struct sockaddr_in);
|
||||||
|
int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp);
|
||||||
|
|
||||||
|
if (connfd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addconnection(connfd, inet_ntoa(their_addr.sin_addr), is_ssl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int openlistener(int port)
|
||||||
|
{
|
||||||
|
int sd;
|
||||||
|
#ifdef WIN32
|
||||||
|
char tp=1;
|
||||||
|
#else
|
||||||
|
int tp=1;
|
||||||
|
#endif
|
||||||
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
|
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp));
|
||||||
|
my_addr.sin_family = AF_INET; // host byte order
|
||||||
|
my_addr.sin_port = htons((short)port); // short, network byte order
|
||||||
|
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
|
||||||
|
memset(&(my_addr.sin_zero), 0, 8); // zero the rest of the struct
|
||||||
|
|
||||||
|
if (bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
|
||||||
|
{
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(sd, BACKLOG) == -1)
|
||||||
|
{
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
int openlistener6(int port)
|
||||||
|
{
|
||||||
|
int sd,tp;
|
||||||
|
struct sockaddr_in6 my_addr;
|
||||||
|
|
||||||
|
if ((sd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp));
|
||||||
|
memset(&my_addr, 0, sizeof(my_addr));
|
||||||
|
my_addr.sin6_family = AF_INET6;
|
||||||
|
my_addr.sin6_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(sd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
|
||||||
|
{
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(sd, BACKLOG) == -1)
|
||||||
|
{
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user