├── AUTHORS ├── COPYING ├── Makefile ├── README.md ├── gnutls ├── Makefile ├── README ├── demo.crt ├── demo.key ├── spgcrypt.c ├── spgcrypt.h ├── spgnutls.cpp ├── spgnutls.hpp └── testechos.cpp ├── matrixssl ├── Makefile ├── README ├── demo.crt ├── demo.key ├── democa.crt ├── spmatrixssl.cpp ├── spmatrixssl.hpp ├── sslSocket.c ├── sslSocket.h ├── stelnet └── testechos.cpp ├── openssl ├── Makefile ├── README ├── demo.crt ├── demo.key ├── democa.crt ├── spopenssl.cpp ├── spopenssl.hpp ├── stelnet ├── testechos.cpp ├── testhttps.cpp └── testiocphttps.cpp ├── spserver ├── Makefile ├── Makefile.darwin ├── README ├── event_msgqueue.c ├── event_msgqueue.h ├── spbuffer.cpp ├── spbuffer.hpp ├── spdispatcher.cpp ├── spdispatcher.hpp ├── speventcb.cpp ├── speventcb.hpp ├── spexecutor.cpp ├── spexecutor.hpp ├── spgetopt.c ├── spgetopt.h ├── sphandler.cpp ├── sphandler.hpp ├── sphttp.cpp ├── sphttp.hpp ├── sphttpmsg.cpp ├── sphttpmsg.hpp ├── spiochannel.cpp ├── spiochannel.hpp ├── spiocpdispatcher.cpp ├── spiocpdispatcher.hpp ├── spiocpevent.cpp ├── spiocpevent.hpp ├── spiocplfserver.cpp ├── spiocplfserver.hpp ├── spiocpserver.cpp ├── spiocpserver.hpp ├── spioutils.cpp ├── spioutils.hpp ├── splfserver.cpp ├── splfserver.hpp ├── spmsgblock.cpp ├── spmsgblock.hpp ├── spmsgdecoder.cpp ├── spmsgdecoder.hpp ├── spporting.hpp ├── sprequest.cpp ├── sprequest.hpp ├── spresponse.cpp ├── spresponse.hpp ├── spserver.cpp ├── spserver.hpp ├── spsession.cpp ├── spsession.hpp ├── spsmtp.cpp ├── spsmtp.hpp ├── spthread.cpp ├── spthread.hpp ├── spthreadpool.cpp ├── spthreadpool.hpp ├── sputils.cpp ├── sputils.hpp ├── spwin32buffer.cpp ├── spwin32buffer.hpp ├── spwin32iocp.cpp ├── spwin32iocp.hpp ├── spwin32port.cpp ├── spwin32port.hpp ├── testchat.cpp ├── testchat_d.cpp ├── testdispatcher.cpp ├── testecho.cpp ├── testhttp.cpp ├── testhttp_d.cpp ├── testhttpmsg.cpp ├── testiocpchat.cpp ├── testiocpdispatcher.cpp ├── testiocpecho.cpp ├── testiocphttp.cpp ├── testiocpstress.cpp ├── testsmtp.cpp ├── teststress.cpp ├── testthreadpool.cpp └── testunp.cpp ├── sptunnel ├── Makefile ├── README ├── demo.crt ├── demo.key ├── democa.crt ├── sptunnel.cpp ├── sptunnelimpl.cpp └── sptunnelimpl.hpp ├── win32 ├── README ├── spgnutls │ └── spgnutls.dsp ├── spmatrixssl │ └── spmatrixssl.dsp ├── spopenssl │ └── spopenssl.dsp ├── spserver.dsp ├── spserver.dsw ├── sptunnel │ └── sptunnel.dsp ├── spxyssl │ └── spxyssl.dsp ├── testiocpchat │ └── testiocpchat.dsp ├── testiocpdispatcher │ └── testiocpdispatcher.dsp ├── testiocpecho │ └── testiocpecho.dsp ├── testiocphttp │ └── testiocphttp.dsp ├── testiocphttps │ └── testiocphttps.dsp ├── testiocpstress │ └── testiocpstress.dsp └── testthreadpool │ └── testthreadpool.dsp └── xyssl ├── Makefile ├── README ├── demo.crt ├── demo.key ├── spxyssl.cpp ├── spxyssl.hpp └── testechos.cpp /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | Author: 3 | 4 | Stephen Liu ** Concept and main design/coding 5 | 6 | Contributors: 7 | 8 | hui23 9 | Jurgen Van Ham 10 | 11 | If I have forgotten your name, please contact me. 12 | 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | ifeq ($(origin version), undefined) 5 | version = 0.9.2 6 | endif 7 | 8 | #-------------------------------------------------------------------- 9 | 10 | all: 11 | @( cd spserver; make ) 12 | 13 | ssl: 14 | @( cd openssl; make ) 15 | 16 | dist: clean spserver-$(version).src.tar.gz 17 | 18 | spserver-$(version).src.tar.gz: 19 | @find . -type f | grep -v CVS | grep -v .svn | sed s:^./:spserver-$(version)/: > MANIFEST 20 | @(cd ..; ln -s spserver spserver-$(version)) 21 | (cd ..; tar cvf - `cat spserver/MANIFEST` | gzip > spserver/spserver-$(version).src.tar.gz) 22 | @(cd ..; rm spserver-$(version)) 23 | 24 | clean: 25 | @( cd spserver; make clean ) 26 | @( cd openssl; make clean ) 27 | @( cd matrixssl; make clean ) 28 | @( cd gnutls; make clean ) 29 | @( cd xyssl; make clean ) 30 | @( cd sptunnel; make clean ) 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SPServer is a server framework library written on C++ that implements the Half-Sync/Half-Async and Leader/Follower patterns. It's based on libevent in order to utilize the best I/O loop on any platform. 2 | 3 | SPServer can simplify TCP server construction. It is a hybrid system between threaded and event-driven, and exploits the advantages of both programming models. It exposes a threaded programming style to programmers, while simultaneously using event-driven style to process network connection. 4 | 5 | SPServer also include an embedded http server framework -- sphttp. sphttp can simplify to add web server functionality to any C++ app. It is useful for adding Web-based administration or statistics to any C++ program or becoming the server framework of XML-RPC or JSON-RPC. 6 | 7 | SPServer is available through the FreeBSD Ports Collection. 8 | 9 | 10 | Changelog: 11 | 12 | Changes in version 0.9.5 (12.13.2009) 13 | ------------------------------------- 14 | * Fix memory leak in IOCP Server. 15 | * Improve SP_DotTermMsgDecoder performance. 16 | 17 | Changes in version 0.9.4 (03.15.2009) 18 | ------------------------------------- 19 | * Added an embedded SMTP server based on spserver and some memory leak bugfixes. 20 | 21 | Changes in version 0.9.3 (09.24.2008) 22 | ------------------------------------- 23 | * Add judgement in SP_DefaultMsgDecoder to avoid dead loop 24 | * Safe to close session with empty response 25 | * Add toCloseList in SP_Response, using to terminate other sessions 26 | * Set client ip in SP_Request when using SP_Dispatcher/SP_IocpDispatcher 27 | * Porting to MacOS 28 | 29 | Changes in version 0.9.2 (06.28.2008) 30 | ------------------------------------- 31 | * Xyssl socket IO layer for spserver was added 32 | * An abstract layer for socket IO was added for IOCP server framework 33 | * Porting openssl plugin for IOCP server framework 34 | * Porting sptunnel to win32 35 | 36 | Changes in version 0.9.1 (05.24.2008) 37 | ------------------------------------- 38 | * A win32 IOCP based server framework was added. 39 | * A win32 IOCP based dispatcher was added. 40 | * Improve demo programs' performance. 41 | 42 | Changes in version 0.9.0 (04.19.2008) 43 | ------------------------------------- 44 | * Porting to win32 with MSVC6 45 | * Fix out of buffer write of SP_Buffer (From Jurgen Van Ham) 46 | * Change default listen backlog to 1024 47 | * Remove dependency of libevent/config.h 48 | 49 | Changes in version 0.8.5 (10.27.2007) 50 | ------------------------------------- 51 | * GNUTLS socket IO layer for spserver was added 52 | 53 | Changes in version 0.8 (08.22.2007) 54 | ------------------------------------- 55 | * Matrixssl socket IO layer for spserver was added 56 | * Directory structure refactor 57 | 58 | Changes in version 0.7.5 (08.12.2007) 59 | ------------------------------------- 60 | * An ssl proxy, sptunnel, was added 61 | 62 | Changes in version 0.7 (08.11.2007) 63 | ------------------------------------- 64 | * A timer mechanism for SP_Dispatcher was added 65 | * An abstract layer for socket IO was added 66 | * An openssl socket IO layer for spserver was added 67 | 68 | Changes in version 0.6 (07.01.2007) 69 | ------------------------------------- 70 | * An Leader/Follower thread pool server was added 71 | 72 | Changes in version 0.5 (06.23.2007) 73 | ------------------------------------- 74 | * A socket dispatcher that applies a half-async/half-sync thread pool for server/client sockets was added. 75 | 76 | Changes in version 0.4 (06.12.2007) 77 | ------------------------------------- 78 | * A race condition in get/set of MsgDecoder was fixed. 79 | 80 | Changes in version 0.3 (05.15.2007) 81 | ------------------------------------- 82 | * A message block class was added to enable efficient manipulation of arbitrarily large messages without incurring much memory copying overhead. 83 | 84 | Changes in version 0.2.1 (05.10.2007) 85 | ------------------------------------- 86 | * Added an embedded HTTP server based on spserver and some minor bugfixes. 87 | 88 | Changes in version 0.1 (03.14.2007) 89 | ------------------------------------- 90 | * version 0.1 release 91 | -------------------------------------------------------------------------------- /gnutls/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread -lresolv 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | GNUTLS_INCL = -I/usr/local/include/ 15 | GNUTLS_LIB = -L/usr/local/lib -lgcrypt -lgpg-error -lgnutls -lgnutls-extra -lstdc++ 16 | 17 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 18 | 19 | SPSERVER_INCL = -I../spserver 20 | SPSERVER_LIB = -L../spserver -lspserver 21 | 22 | CFLAGS += $(GNUTLS_INCL) $(SPSERVER_INCL) 23 | LDFLAGS += $(LIBEVENT_LIB) $(GNUTLS_LIB) $(SPSERVER_LIB) 24 | 25 | #-------------------------------------------------------------------- 26 | 27 | LIBOBJS = spgnutls.o spgcrypt.o 28 | 29 | TARGET = libspgnutls.so \ 30 | testechos 31 | 32 | #-------------------------------------------------------------------- 33 | 34 | all: $(TARGET) 35 | 36 | libspgnutls.so: $(LIBOBJS) 37 | $(LINKER) $(SOFLAGS) $^ -o $@ 38 | 39 | testechos: testechos.o 40 | $(LINKER) $(LDFLAGS) $^ -L. -lspgnutls -o $@ 41 | 42 | clean: 43 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 44 | 45 | #-------------------------------------------------------------------- 46 | 47 | # make rule 48 | %.o : %.c 49 | $(CC) $(CFLAGS) -c $^ -o $@ 50 | 51 | %.o : %.cpp 52 | $(CC) $(CFLAGS) -c $^ -o $@ 53 | 54 | -------------------------------------------------------------------------------- /gnutls/README: -------------------------------------------------------------------------------- 1 | spserver/gnutls README 2 | 3 | 1.Introduction 4 | 5 | spserver/gnutls is a plugin for spserver, it enables spserver to support gnutls. 6 | 7 | 2.Building 8 | 9 | Before building spserver/gnutls, GNUTLS must been installed. 10 | 11 | You can donwload GNUTLS from its home page: 12 | 13 | ftp://ftp.gnupg.org/gcrypt/ 14 | 15 | Edit spserver/gnutls/Makefile to specify the path of GNUTLS: 16 | 17 | GNUTLS_INCL = -I 18 | GNUTLS_LIB = -L -lgcrypt -lgpg-error \ 19 | -lgnutls -lgnutls-extra -lstdc++ 20 | 21 | To build libspgnutls.so, type 22 | 23 | $ cd spserver/gnutls 24 | $ make 25 | 26 | This will build all the targets include examples. You can run the 27 | example programs: 28 | 29 | bash-2.05a$ ./testechos 30 | testechos[28745]: Listen on port [1995] 31 | 32 | You can use the stelnet to visit: 33 | 34 | gnutls-cli -p 1995 127.0.0.1 35 | 36 | 37 | Enjoy! 38 | 39 | -- stephen liu 40 | 41 | -------------------------------------------------------------------------------- /gnutls/demo.crt: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 2 (0x2) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=NO, ST=TEST, L=TEST, O=TEST, OU=TEST, CN=TEST/Email=TEST@TEST.COM 7 | Validity 8 | Not Before: Dec 18 02:06:26 2000 GMT 9 | Not After : Dec 18 02:06:26 2001 GMT 10 | Subject: C=NO, ST=TEST, L=TEST, O=TEST, OU=DEMO, CN=DEMO/Email=TEST@TEST.COM 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (512 bit) 14 | Modulus (512 bit): 15 | 00:c8:46:d3:a7:b5:da:58:b1:5a:08:6b:28:a8:7b: 16 | a5:9b:4a:83:1e:58:4f:0b:18:9e:aa:83:11:27:97: 17 | 24:92:70:0b:47:f4:c8:74:a1:58:92:19:35:88:b3: 18 | 8a:b4:ae:ee:e2:98:5d:bf:d4:53:b8:c6:0c:a1:da: 19 | be:b6:b2:18:f9 20 | Exponent: 65537 (0x10001) 21 | X509v3 extensions: 22 | X509v3 Basic Constraints: 23 | CA:FALSE 24 | Netscape Comment: 25 | OpenSSL Generated Certificate 26 | X509v3 Subject Key Identifier: 27 | 64:2B:31:23:69:F6:49:10:96:EB:BB:5E:91:F2:12:54:37:E6:B3:6B 28 | X509v3 Authority Key Identifier: 29 | keyid:BA:E8:35:48:75:8B:37:A9:77:48:D5:7A:B3:AB:34:C2:41:7C:FF:0E 30 | DirName:/C=NO/ST=TEST/L=TEST/O=TEST/OU=TEST/CN=TEST/Email=TEST@TEST.COM 31 | serial:00 32 | 33 | Signature Algorithm: md5WithRSAEncryption 34 | c0:36:98:cd:32:2d:65:59:60:a9:c9:ca:fa:ba:d8:d6:b1:89: 35 | 16:8b:ae:a5:6f:ea:c3:a0:b1:55:27:0b:04:42:a2:2f:33:39: 36 | fc:46:79:5d:63:33:bf:a7:b2:32:01:a7:17:13:6b:c6:67:2b: 37 | ee:ee:37:3e:64:e4:bb:5d:e9:28:5b:1b:46:33:3d:c1:27:fb: 38 | 8c:ff:ef:e5:49:22:18:e7:6a:03:4c:80:67:45:41:7c:48:e2: 39 | a8:a4:d4:7e:18:09:1d:2d:ab:bd:f0:97:ac:ba:5a:28:46:51: 40 | a0:d3:80:b2:83:70:d4:9a:a6:d0:5f:46:77:43:0e:aa:25:d3: 41 | 19:3c 42 | test haha 43 | -----BEGIN CERTIFICATE----- 44 | MIIDHTCCAoagAwIBAgIBAjANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 45 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 46 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 47 | RVNULkNPTTAeFw0wMDEyMTgwMjA2MjZaFw0wMTEyMTgwMjA2MjZaMHYxCzAJBgNV 48 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 49 | RVNUMQ0wCwYDVQQLEwRERU1PMQ0wCwYDVQQDEwRERU1PMRwwGgYJKoZIhvcNAQkB 50 | Fg1URVNUQFRFU1QuQ09NMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMhG06e12lix 51 | WghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHShWJIZNYizirSu7uKYXb/UU7jG 52 | DKHavrayGPkCAwEAAaOB/jCB+zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P 53 | cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUZCsxI2n2SRCW 54 | 67tekfISVDfms2swgaAGA1UdIwSBmDCBlYAUuug1SHWLN6l3SNV6s6s0wkF8/w6h 55 | eqR4MHYxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNU 56 | MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRww 57 | GgYJKoZIhvcNAQkBFg1URVNUQFRFU1QuQ09NggEAMA0GCSqGSIb3DQEBBAUAA4GB 58 | AMA2mM0yLWVZYKnJyvq62NaxiRaLrqVv6sOgsVUnCwRCoi8zOfxGeV1jM7+nsjIB 59 | pxcTa8ZnK+7uNz5k5Ltd6ShbG0YzPcEn+4z/7+VJIhjnagNMgGdFQXxI4qik1H4Y 60 | CR0tq73wl6y6WihGUaDTgLKDcNSaptBfRndDDqol0xk8 61 | -----END CERTIFICATE----- 62 | -------------------------------------------------------------------------------- /gnutls/demo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIBOgIBAAJBAMhG06e12lixWghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHSh 3 | WJIZNYizirSu7uKYXb/UU7jGDKHavrayGPkCAwEAAQJAMXKzTWQr/dwEA7IZfsfQ 4 | kq/qAbMCCRZSDn1/3cuGfxT0Vd/gIXLP+yXdEC1jW1LJoBIhWQLnZHEwyKAS6OIz 5 | 0QIhAP4U3GC+SHfJ27PSGv+hjXp47QNbvvmL5T+SXqqHjqgVAiEAycn2FtiNmkzW 6 | ttLkfdZL609c49d+ac0OiTkMfBTbolUCIA9HZ901dBwn+ls85jy7FUvpG6+ZA8nz 7 | 3KxO+/xbPHvlAiB78tJ2tg5E+W3qXyB7K2b244jrazL7SjnjkGda0HUZAQIhAJVp 8 | ms+n0W3jGqEqUntQFbAfjnUo5FIZCjbiz4glt3Do 9 | -----END RSA PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /gnutls/spgcrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | GCRY_THREAD_OPTION_PTHREAD_IMPL; 14 | 15 | int sp_init_gcrypt_pthread() 16 | { 17 | return gcry_control( GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread ); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /gnutls/spgcrypt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spgcrypt_h__ 7 | #define __spgcrypt_h__ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | int sp_init_gcrypt_pthread(); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /gnutls/spgnutls.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "spporting.hpp" 15 | 16 | #include "spgnutls.hpp" 17 | #include "spsession.hpp" 18 | #include "spbuffer.hpp" 19 | #include "speventcb.hpp" 20 | #include "sputils.hpp" 21 | #include "spmsgblock.hpp" 22 | #include "spioutils.hpp" 23 | 24 | #ifdef WIN32 25 | #ifndef HAVE_SSIZE_T 26 | typedef long ssize_t; 27 | #endif 28 | #endif 29 | 30 | #include 31 | #include "spgcrypt.h" 32 | 33 | SP_GnutlsChannel :: SP_GnutlsChannel( struct gnutls_certificate_credentials_st * cred ) 34 | { 35 | mCred = cred; 36 | mTls = NULL; 37 | } 38 | 39 | SP_GnutlsChannel :: ~SP_GnutlsChannel() 40 | { 41 | if( NULL != mTls ) 42 | { 43 | /* do not wait for the peer to close the connection. 44 | */ 45 | gnutls_bye( mTls, GNUTLS_SHUT_WR ); 46 | 47 | gnutls_deinit( mTls ); 48 | } 49 | mTls = NULL; 50 | } 51 | 52 | int SP_GnutlsChannel :: init( int fd ) 53 | { 54 | gnutls_init( &mTls, GNUTLS_SERVER ); 55 | 56 | /* avoid calling all the priority functions, since the defaults 57 | * are adequate. 58 | */ 59 | gnutls_set_default_priority( mTls ); 60 | 61 | gnutls_credentials_set( mTls, GNUTLS_CRD_CERTIFICATE, mCred ); 62 | 63 | /* request client certificate if any. 64 | */ 65 | gnutls_certificate_server_set_request( mTls, GNUTLS_CERT_REQUEST ); 66 | 67 | gnutls_dh_set_prime_bits( mTls, SP_GnutlsChannelFactory::DH_BITS ); 68 | 69 | gnutls_transport_set_ptr( mTls, (gnutls_transport_ptr_t) fd ); 70 | 71 | /* we run in an independence thread, and we can block when gnutls_handshake */ 72 | 73 | SP_IOUtils::setBlock( fd ); 74 | int ret = gnutls_handshake( mTls ); 75 | if( ret < 0 ) { 76 | sp_syslog( LOG_EMERG, "gnutls_handshake fail, %s", gnutls_strerror( ret ) ); 77 | return -1; 78 | } 79 | 80 | SP_IOUtils::setNonblock( fd ); 81 | 82 | return 0; 83 | } 84 | 85 | int SP_GnutlsChannel :: receive( SP_Session * session ) 86 | { 87 | char buffer[ 4096 ] = { 0 }; 88 | 89 | int ret = gnutls_record_recv( mTls, buffer, sizeof( buffer ) ); 90 | if( ret > 0 ) { 91 | session->getInBuffer()->append( buffer, ret ); 92 | } else if( ret < 0 ) { 93 | sp_syslog( LOG_EMERG, "gnutls_record_recv fail, %s", gnutls_strerror( ret ) ); 94 | } 95 | 96 | return ret; 97 | } 98 | 99 | int SP_GnutlsChannel :: write_vec( struct iovec * iovArray, int iovSize ) 100 | { 101 | int len = 0; 102 | for( int i = 0; i < iovSize; i++ ) { 103 | int ret = gnutls_record_send( mTls, iovArray[i].iov_base, iovArray[i].iov_len ); 104 | if( ret > 0 ) len += ret; 105 | if( ret != (int)iovArray[i].iov_len ) break; 106 | } 107 | 108 | return len; 109 | } 110 | 111 | //--------------------------------------------------------- 112 | 113 | SP_GnutlsChannelFactory :: SP_GnutlsChannelFactory() 114 | { 115 | mCred = NULL; 116 | } 117 | 118 | SP_GnutlsChannelFactory :: ~SP_GnutlsChannelFactory() 119 | { 120 | if( NULL != mCred ) 121 | { 122 | gnutls_certificate_free_credentials( mCred ); 123 | gnutls_global_deinit(); 124 | } 125 | mCred = NULL; 126 | } 127 | 128 | SP_IOChannel * SP_GnutlsChannelFactory :: create() const 129 | { 130 | return new SP_GnutlsChannel( mCred ); 131 | } 132 | 133 | int SP_GnutlsChannelFactory :: init( const char * certFile, const char * keyFile ) 134 | { 135 | #ifndef WIN32 136 | sp_init_gcrypt_pthread(); 137 | #endif 138 | 139 | int ret = 0; 140 | 141 | if( ( ret = gnutls_global_init() ) < 0 ) 142 | { 143 | sp_syslog( LOG_ERR, "global_init: %s\n", gnutls_strerror( ret ) ); 144 | return -1; 145 | } 146 | 147 | gnutls_certificate_allocate_credentials( &mCred ); 148 | 149 | //gnutls_certificate_set_x509_trust_file( mCred, caFile, GNUTLS_X509_FMT_PEM ); 150 | //gnutls_certificate_set_x509_crl_file( mCred, crlFile, GNUTLS_X509_FMT_PEM ); 151 | 152 | gnutls_certificate_set_x509_key_file( mCred, certFile, keyFile, GNUTLS_X509_FMT_PEM ); 153 | 154 | static gnutls_dh_params_t dh_params; 155 | 156 | /* Generate Diffie Hellman parameters - for use with DHE 157 | * kx algorithms. These should be discarded and regenerated 158 | * once a day, once a week or once a month. Depending on the 159 | * security requirements. 160 | */ 161 | gnutls_dh_params_init( &dh_params ); 162 | gnutls_dh_params_generate2( dh_params, DH_BITS ); 163 | 164 | gnutls_certificate_set_dh_params( mCred, dh_params ); 165 | 166 | return 0; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /gnutls/spgnutls.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spgnutls_hpp__ 7 | #define __spgnutls_hpp__ 8 | 9 | #include "spiochannel.hpp" 10 | 11 | struct gnutls_session_int; 12 | struct gnutls_certificate_credentials_st; 13 | 14 | class SP_GnutlsChannel : public SP_IOChannel { 15 | public: 16 | SP_GnutlsChannel( struct gnutls_certificate_credentials_st * cred ); 17 | virtual ~SP_GnutlsChannel(); 18 | 19 | virtual int init( int fd ); 20 | 21 | virtual int receive( SP_Session * session ); 22 | 23 | private: 24 | virtual int write_vec( struct iovec * vector, int count ); 25 | 26 | gnutls_session_int * mTls; 27 | gnutls_certificate_credentials_st * mCred; 28 | }; 29 | 30 | class SP_GnutlsChannelFactory : public SP_IOChannelFactory { 31 | public: 32 | 33 | enum { DH_BITS = 1024 }; 34 | 35 | SP_GnutlsChannelFactory(); 36 | virtual ~SP_GnutlsChannelFactory(); 37 | 38 | virtual SP_IOChannel * create() const; 39 | 40 | int init( const char * certFile, const char * keyFile ); 41 | 42 | private: 43 | gnutls_certificate_credentials_st * mCred; 44 | }; 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /gnutls/testechos.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spmsgdecoder.hpp" 14 | #include "spbuffer.hpp" 15 | 16 | #include "spserver.hpp" 17 | #include "sphandler.hpp" 18 | #include "spresponse.hpp" 19 | #include "sprequest.hpp" 20 | #include "spgnutls.hpp" 21 | #include "sputils.hpp" 22 | 23 | class SP_EchoHandler : public SP_Handler { 24 | public: 25 | SP_EchoHandler(){} 26 | virtual ~SP_EchoHandler(){} 27 | 28 | // return -1 : terminate session, 0 : continue 29 | virtual int start( SP_Request * request, SP_Response * response ) { 30 | request->setMsgDecoder( new SP_MultiLineMsgDecoder() ); 31 | response->getReply()->getMsg()->append( 32 | "Welcome to line echo server, enter 'quit' to quit.\r\n" ); 33 | 34 | return 0; 35 | } 36 | 37 | // return -1 : terminate session, 0 : continue 38 | virtual int handle( SP_Request * request, SP_Response * response ) { 39 | SP_MultiLineMsgDecoder * decoder = (SP_MultiLineMsgDecoder*)request->getMsgDecoder(); 40 | SP_CircleQueue * queue = decoder->getQueue(); 41 | 42 | int ret = 0; 43 | for( ; NULL != queue->top(); ) { 44 | char * line = (char*)queue->pop(); 45 | 46 | if( 0 != strcasecmp( line, "quit" ) ) { 47 | response->getReply()->getMsg()->append( line ); 48 | response->getReply()->getMsg()->append( "\r\n" ); 49 | } else { 50 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 51 | ret = -1; 52 | } 53 | 54 | free( line ); 55 | } 56 | 57 | return ret; 58 | } 59 | 60 | virtual void error( SP_Response * response ) {} 61 | 62 | virtual void timeout( SP_Response * response ) {} 63 | 64 | virtual void close() {} 65 | }; 66 | 67 | class SP_EchoHandlerFactory : public SP_HandlerFactory { 68 | public: 69 | SP_EchoHandlerFactory() {} 70 | virtual ~SP_EchoHandlerFactory() {} 71 | 72 | virtual SP_Handler * create() const { 73 | return new SP_EchoHandler(); 74 | } 75 | }; 76 | 77 | //--------------------------------------------------------- 78 | 79 | int main( int argc, char * argv[] ) 80 | { 81 | #ifdef LOG_PERROR 82 | openlog( "testechos", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 83 | #else 84 | openlog( "testechos", LOG_CONS | LOG_PID, LOG_USER ); 85 | #endif 86 | 87 | int port = 1995; 88 | 89 | SP_Server server( "", port, new SP_EchoHandlerFactory() ); 90 | 91 | SP_GnutlsChannelFactory * factory = new SP_GnutlsChannelFactory(); 92 | factory->init( "demo.crt", "demo.key" ); 93 | server.setIOChannelFactory( factory ); 94 | 95 | server.runForever(); 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /matrixssl/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread -lresolv 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | MASSL_INCL = -I$(HOME)/matrixssl-1-8-3-open/ 15 | MASSL_LIB = -L$(HOME)/matrixssl-1-8-3-open/src -lmatrixssl 16 | 17 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 18 | 19 | SPSERVER_INCL = -I../spserver 20 | SPSERVER_LIB = -L../spserver -lspserver 21 | 22 | CFLAGS += $(MASSL_INCL) $(SPSERVER_INCL) 23 | LDFLAGS += $(MASSL_LIB) $(SPSERVER_LIB) $(LIBEVENT_LIB) 24 | 25 | #-------------------------------------------------------------------- 26 | 27 | LIBOBJS = sslSocket.o spmatrixssl.o 28 | 29 | TARGET = libspmatrixssl.so \ 30 | testechos 31 | 32 | #-------------------------------------------------------------------- 33 | 34 | all: $(TARGET) 35 | 36 | libspmatrixssl.so: $(LIBOBJS) 37 | $(LINKER) $(SOFLAGS) $^ -o $@ 38 | 39 | testechos: testechos.o 40 | $(LINKER) $(LDFLAGS) $^ -L. -lspmatrixssl -o $@ 41 | 42 | clean: 43 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 44 | 45 | #-------------------------------------------------------------------- 46 | 47 | # make rule 48 | %.o : %.c 49 | $(CC) $(CFLAGS) -c $^ -o $@ 50 | 51 | %.o : %.cpp 52 | $(CC) $(CFLAGS) -c $^ -o $@ 53 | 54 | -------------------------------------------------------------------------------- /matrixssl/README: -------------------------------------------------------------------------------- 1 | spserver/matrixssl README 2 | 3 | 1.Introduction 4 | 5 | spserver/matrixssl is a plugin for spserver, it enables spserver to support ssl. 6 | 7 | 2.Building 8 | 9 | Before building spserver/matrixssl, MatrixSSL must been installed. 10 | 11 | You can donwload MatrixSSL from its home page: 12 | 13 | http://www.matrixssl.org/ 14 | 15 | Edit spserver/matrixssl/Makefile to specify the path of MatrixSSL: 16 | 17 | MASSL_INCL = -I 18 | MASSL_LIB = -L -lmatrixssl 19 | 20 | To build libspmatrixssl.so, type 21 | 22 | $ cd spserver/matrixssl 23 | $ make 24 | 25 | This will build all the targets include examples. You can run the 26 | example programs: 27 | 28 | bash-2.05a$ ./testechos 29 | testechos[28745]: Listen on port [1995] 30 | 31 | You can use the stelnet to visit: 32 | 33 | ./stelnet 127.0.0.1 1995 34 | 35 | 36 | Enjoy! 37 | 38 | -- stephen liu 39 | 40 | -------------------------------------------------------------------------------- /matrixssl/demo.crt: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 2 (0x2) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=NO, ST=TEST, L=TEST, O=TEST, OU=TEST, CN=TEST/Email=TEST@TEST.COM 7 | Validity 8 | Not Before: Dec 18 02:06:26 2000 GMT 9 | Not After : Dec 18 02:06:26 2001 GMT 10 | Subject: C=NO, ST=TEST, L=TEST, O=TEST, OU=DEMO, CN=DEMO/Email=TEST@TEST.COM 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (512 bit) 14 | Modulus (512 bit): 15 | 00:c8:46:d3:a7:b5:da:58:b1:5a:08:6b:28:a8:7b: 16 | a5:9b:4a:83:1e:58:4f:0b:18:9e:aa:83:11:27:97: 17 | 24:92:70:0b:47:f4:c8:74:a1:58:92:19:35:88:b3: 18 | 8a:b4:ae:ee:e2:98:5d:bf:d4:53:b8:c6:0c:a1:da: 19 | be:b6:b2:18:f9 20 | Exponent: 65537 (0x10001) 21 | X509v3 extensions: 22 | X509v3 Basic Constraints: 23 | CA:FALSE 24 | Netscape Comment: 25 | OpenSSL Generated Certificate 26 | X509v3 Subject Key Identifier: 27 | 64:2B:31:23:69:F6:49:10:96:EB:BB:5E:91:F2:12:54:37:E6:B3:6B 28 | X509v3 Authority Key Identifier: 29 | keyid:BA:E8:35:48:75:8B:37:A9:77:48:D5:7A:B3:AB:34:C2:41:7C:FF:0E 30 | DirName:/C=NO/ST=TEST/L=TEST/O=TEST/OU=TEST/CN=TEST/Email=TEST@TEST.COM 31 | serial:00 32 | 33 | Signature Algorithm: md5WithRSAEncryption 34 | c0:36:98:cd:32:2d:65:59:60:a9:c9:ca:fa:ba:d8:d6:b1:89: 35 | 16:8b:ae:a5:6f:ea:c3:a0:b1:55:27:0b:04:42:a2:2f:33:39: 36 | fc:46:79:5d:63:33:bf:a7:b2:32:01:a7:17:13:6b:c6:67:2b: 37 | ee:ee:37:3e:64:e4:bb:5d:e9:28:5b:1b:46:33:3d:c1:27:fb: 38 | 8c:ff:ef:e5:49:22:18:e7:6a:03:4c:80:67:45:41:7c:48:e2: 39 | a8:a4:d4:7e:18:09:1d:2d:ab:bd:f0:97:ac:ba:5a:28:46:51: 40 | a0:d3:80:b2:83:70:d4:9a:a6:d0:5f:46:77:43:0e:aa:25:d3: 41 | 19:3c 42 | test haha 43 | -----BEGIN CERTIFICATE----- 44 | MIIDHTCCAoagAwIBAgIBAjANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 45 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 46 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 47 | RVNULkNPTTAeFw0wMDEyMTgwMjA2MjZaFw0wMTEyMTgwMjA2MjZaMHYxCzAJBgNV 48 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 49 | RVNUMQ0wCwYDVQQLEwRERU1PMQ0wCwYDVQQDEwRERU1PMRwwGgYJKoZIhvcNAQkB 50 | Fg1URVNUQFRFU1QuQ09NMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMhG06e12lix 51 | WghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHShWJIZNYizirSu7uKYXb/UU7jG 52 | DKHavrayGPkCAwEAAaOB/jCB+zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P 53 | cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUZCsxI2n2SRCW 54 | 67tekfISVDfms2swgaAGA1UdIwSBmDCBlYAUuug1SHWLN6l3SNV6s6s0wkF8/w6h 55 | eqR4MHYxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNU 56 | MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRww 57 | GgYJKoZIhvcNAQkBFg1URVNUQFRFU1QuQ09NggEAMA0GCSqGSIb3DQEBBAUAA4GB 58 | AMA2mM0yLWVZYKnJyvq62NaxiRaLrqVv6sOgsVUnCwRCoi8zOfxGeV1jM7+nsjIB 59 | pxcTa8ZnK+7uNz5k5Ltd6ShbG0YzPcEn+4z/7+VJIhjnagNMgGdFQXxI4qik1H4Y 60 | CR0tq73wl6y6WihGUaDTgLKDcNSaptBfRndDDqol0xk8 61 | -----END CERTIFICATE----- 62 | -------------------------------------------------------------------------------- /matrixssl/demo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIBOgIBAAJBAMhG06e12lixWghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHSh 3 | WJIZNYizirSu7uKYXb/UU7jGDKHavrayGPkCAwEAAQJAMXKzTWQr/dwEA7IZfsfQ 4 | kq/qAbMCCRZSDn1/3cuGfxT0Vd/gIXLP+yXdEC1jW1LJoBIhWQLnZHEwyKAS6OIz 5 | 0QIhAP4U3GC+SHfJ27PSGv+hjXp47QNbvvmL5T+SXqqHjqgVAiEAycn2FtiNmkzW 6 | ttLkfdZL609c49d+ac0OiTkMfBTbolUCIA9HZ901dBwn+ls85jy7FUvpG6+ZA8nz 7 | 3KxO+/xbPHvlAiB78tJ2tg5E+W3qXyB7K2b244jrazL7SjnjkGda0HUZAQIhAJVp 8 | ms+n0W3jGqEqUntQFbAfjnUo5FIZCjbiz4glt3Do 9 | -----END RSA PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /matrixssl/democa.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAp+gAwIBAgIBADANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 3 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 4 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 5 | RVNULkNPTTAeFw0wMDEyMTQwNjE2MjRaFw0wMTEyMTQwNjE2MjRaMHYxCzAJBgNV 6 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 7 | RVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRwwGgYJKoZIhvcNAQkB 8 | Fg1URVNUQFRFU1QuQ09NMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZfu/c 9 | MfHECMJDd94P0xnoKaVvSx1sR6ZUOhoExEmlOLN3vGHingNqeuhHWhfrEV3TuCJU 10 | JKuzxG/63PO1nRKl74j/14t0MRk3Mfu9xJN4VLwxsEy1v46MgAqwKk/nad7xd9kl 11 | +LPfsy2dOYGhhsO/HL2FZ3M+yPlAXQmIIcwciwIDAQABo4HTMIHQMB0GA1UdDgQW 12 | BBS66DVIdYs3qXdI1XqzqzTCQXz/DjCBoAYDVR0jBIGYMIGVgBS66DVIdYs3qXdI 13 | 1XqzqzTCQXz/DqF6pHgwdjELMAkGA1UEBhMCTk8xDTALBgNVBAgTBFRFU1QxDTAL 14 | BgNVBAcTBFRFU1QxDTALBgNVBAoTBFRFU1QxDTALBgNVBAsTBFRFU1QxDTALBgNV 15 | BAMTBFRFU1QxHDAaBgkqhkiG9w0BCQEWDVRFU1RAVEVTVC5DT02CAQAwDAYDVR0T 16 | BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQCFth61VGXHwzhy2zX7gDSSmut2RSYg 17 | 4M0a1pNkkFZjHm4Z4KN9NJQjOgBFrm1tyg+kp9eI/yY0ug4LEZ9mIVudVAluf6wV 18 | edlnf5Fs28OB/vBUR7Vew+5UET5bC3d1Etnu/h1nDLkFiM0fv2bOPkkMCXzeI08G 19 | hz7yss+W7/R7Iw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /matrixssl/spmatrixssl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "spporting.hpp" 13 | 14 | #include "spmatrixssl.hpp" 15 | #include "spioutils.hpp" 16 | #include "spsession.hpp" 17 | #include "spbuffer.hpp" 18 | #include "speventcb.hpp" 19 | #include "sputils.hpp" 20 | #include "spmsgblock.hpp" 21 | 22 | #include "sslSocket.h" 23 | 24 | SP_MatrixsslChannel :: SP_MatrixsslChannel( sslKeys_t * keys ) 25 | { 26 | mKeys = keys; 27 | mConn = NULL; 28 | } 29 | 30 | SP_MatrixsslChannel :: ~SP_MatrixsslChannel() 31 | { 32 | if( NULL != mConn ) { 33 | sslFreeConnection( &mConn ); 34 | } 35 | } 36 | 37 | int SP_MatrixsslChannel :: init( int fd ) 38 | { 39 | SP_IOUtils::setBlock( fd ); 40 | 41 | int ret = sslAccept( &mConn, fd, mKeys, NULL, 0 ); 42 | 43 | SP_IOUtils::setNonblock( fd ); 44 | 45 | if( 0 != ret ) { 46 | sp_syslog( LOG_EMERG, "sslAccept fail" ); 47 | return -1; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | int SP_MatrixsslChannel :: receive( SP_Session * session ) 54 | { 55 | char buffer[ 4096 ] = { 0 }; 56 | 57 | int ret = sslRead( mConn, buffer, sizeof( buffer ), &errno ); 58 | if( ret > 0 ) { 59 | session->getInBuffer()->append( buffer, ret ); 60 | } else if( ret < 0 ) { 61 | sp_syslog( LOG_EMERG, "sslRead fail" ); 62 | } 63 | 64 | return ret; 65 | } 66 | 67 | int SP_MatrixsslChannel :: write_vec( struct iovec * iovArray, int iovSize ) 68 | { 69 | int len = 0; 70 | 71 | for( int i = 0; i < iovSize; i++ ) { 72 | int ret = sslWrite( mConn, (char*)iovArray[i].iov_base, iovArray[i].iov_len, &errno ); 73 | if( ret > 0 ) len += ret; 74 | if( ret != (int)iovArray[i].iov_len ) break; 75 | } 76 | 77 | return len; 78 | } 79 | 80 | //--------------------------------------------------------- 81 | 82 | SP_MatrixsslChannelFactory :: SP_MatrixsslChannelFactory() 83 | { 84 | mKeys = NULL; 85 | } 86 | 87 | SP_MatrixsslChannelFactory :: ~SP_MatrixsslChannelFactory() 88 | { 89 | matrixSslFreeKeys( mKeys ); 90 | matrixSslClose(); 91 | } 92 | 93 | SP_IOChannel * SP_MatrixsslChannelFactory :: create() const 94 | { 95 | return new SP_MatrixsslChannel( mKeys ); 96 | } 97 | 98 | int SP_MatrixsslChannelFactory :: init( const char * certFile, const char * keyFile ) 99 | { 100 | if( matrixSslOpen() < 0 ) { 101 | sp_syslog( LOG_WARNING, "matrixSslOpen failed" ); 102 | } 103 | 104 | if( matrixSslReadKeys( &mKeys, certFile, keyFile, NULL, NULL ) < 0 ) { 105 | sp_syslog( LOG_WARNING, "Error reading or parsing %s or %s.", certFile, keyFile ); 106 | } 107 | 108 | return 0; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /matrixssl/spmatrixssl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spmatrixssl_hpp__ 7 | #define __spmatrixssl_hpp__ 8 | 9 | #include "spiochannel.hpp" 10 | 11 | typedef struct tagSslConn sslConn_t; 12 | 13 | typedef int int32; 14 | typedef int32 sslKeys_t; 15 | 16 | class SP_MatrixsslChannel : public SP_IOChannel { 17 | public: 18 | SP_MatrixsslChannel( sslKeys_t * keys ); 19 | virtual ~SP_MatrixsslChannel(); 20 | 21 | virtual int init( int fd ); 22 | 23 | virtual int receive( SP_Session * session ); 24 | 25 | private: 26 | virtual int write_vec( struct iovec * iovArray, int iovSize ); 27 | 28 | sslKeys_t * mKeys; 29 | sslConn_t * mConn; 30 | }; 31 | 32 | class SP_MatrixsslChannelFactory : public SP_IOChannelFactory { 33 | public: 34 | SP_MatrixsslChannelFactory(); 35 | virtual ~SP_MatrixsslChannelFactory(); 36 | 37 | virtual SP_IOChannel * create() const; 38 | 39 | int init( const char * certFile, const char * keyFile ); 40 | 41 | private: 42 | sslKeys_t * mKeys; 43 | }; 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /matrixssl/stelnet: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec openssl s_client -connect $1:$2 -crlf -CApath democa.crt 4 | -------------------------------------------------------------------------------- /matrixssl/testechos.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spmsgdecoder.hpp" 14 | #include "spbuffer.hpp" 15 | 16 | #include "spserver.hpp" 17 | #include "sphandler.hpp" 18 | #include "spresponse.hpp" 19 | #include "sprequest.hpp" 20 | #include "spmatrixssl.hpp" 21 | #include "sputils.hpp" 22 | 23 | class SP_EchoHandler : public SP_Handler { 24 | public: 25 | SP_EchoHandler(){} 26 | virtual ~SP_EchoHandler(){} 27 | 28 | // return -1 : terminate session, 0 : continue 29 | virtual int start( SP_Request * request, SP_Response * response ) { 30 | request->setMsgDecoder( new SP_MultiLineMsgDecoder() ); 31 | response->getReply()->getMsg()->append( 32 | "Welcome to line echo server, enter 'quit' to quit.\r\n" ); 33 | 34 | return 0; 35 | } 36 | 37 | // return -1 : terminate session, 0 : continue 38 | virtual int handle( SP_Request * request, SP_Response * response ) { 39 | SP_MultiLineMsgDecoder * decoder = (SP_MultiLineMsgDecoder*)request->getMsgDecoder(); 40 | SP_CircleQueue * queue = decoder->getQueue(); 41 | 42 | int ret = 0; 43 | for( ; NULL != queue->top(); ) { 44 | char * line = (char*)queue->pop(); 45 | 46 | if( 0 != strcasecmp( line, "quit" ) ) { 47 | response->getReply()->getMsg()->append( line ); 48 | response->getReply()->getMsg()->append( "\r\n" ); 49 | } else { 50 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 51 | ret = -1; 52 | } 53 | 54 | free( line ); 55 | } 56 | 57 | return ret; 58 | } 59 | 60 | virtual void error( SP_Response * response ) {} 61 | 62 | virtual void timeout( SP_Response * response ) {} 63 | 64 | virtual void close() {} 65 | }; 66 | 67 | class SP_EchoHandlerFactory : public SP_HandlerFactory { 68 | public: 69 | SP_EchoHandlerFactory() {} 70 | virtual ~SP_EchoHandlerFactory() {} 71 | 72 | virtual SP_Handler * create() const { 73 | return new SP_EchoHandler(); 74 | } 75 | }; 76 | 77 | //--------------------------------------------------------- 78 | 79 | int main( int argc, char * argv[] ) 80 | { 81 | #ifdef LOG_PERROR 82 | openlog( "testechos", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 83 | #else 84 | openlog( "testechos", LOG_CONS | LOG_PID, LOG_USER ); 85 | #endif 86 | 87 | int port = 1995; 88 | 89 | SP_Server server( "", port, new SP_EchoHandlerFactory() ); 90 | 91 | SP_MatrixsslChannelFactory * matrixsslFactory = new SP_MatrixsslChannelFactory(); 92 | matrixsslFactory->init( "demo.crt", "demo.key" ); 93 | server.setIOChannelFactory( matrixsslFactory ); 94 | 95 | server.runForever(); 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /openssl/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread -lresolv 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | OPENSSL_INCL = -I/usr/include/openssl/ 15 | OPENSSL_LIB = -L/usr/lib -lssl -lcrypto 16 | 17 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 18 | 19 | SPSERVER_INCL = -I../spserver 20 | SPSERVER_LIB = -L../spserver -lspserver 21 | 22 | CFLAGS += $(OPENSSL_INCL) $(SPSERVER_INCL) 23 | LDFLAGS += $(LIBEVENT_LIB) $(OPENSSL_LIB) $(SPSERVER_LIB) 24 | 25 | #-------------------------------------------------------------------- 26 | 27 | LIBOBJS = spopenssl.o 28 | 29 | TARGET = libspopenssl.so \ 30 | testechos testhttps 31 | 32 | #-------------------------------------------------------------------- 33 | 34 | all: $(TARGET) 35 | 36 | libspopenssl.so: $(LIBOBJS) 37 | $(LINKER) $(SOFLAGS) $^ -o $@ 38 | 39 | testechos: testechos.o 40 | $(LINKER) $(LDFLAGS) $^ -L. -lspopenssl -o $@ 41 | 42 | testhttps: testhttps.o 43 | $(LINKER) $(LDFLAGS) $^ -L. -lspopenssl -o $@ 44 | 45 | clean: 46 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 47 | 48 | #-------------------------------------------------------------------- 49 | 50 | # make rule 51 | %.o : %.c 52 | $(CC) $(CFLAGS) -c $^ -o $@ 53 | 54 | %.o : %.cpp 55 | $(CC) $(CFLAGS) -c $^ -o $@ 56 | 57 | -------------------------------------------------------------------------------- /openssl/README: -------------------------------------------------------------------------------- 1 | spserver/openssl README 2 | 3 | 1.Introduction 4 | 5 | spserver/openssl is a plugin for spserver, it enables spserver to support ssl. 6 | 7 | 2.Building 8 | 9 | Before building spserver/openssl, OpenSSL must been installed. 10 | 11 | You can donwload OpenSSL from its home page: 12 | 13 | http://www.openssl.org/ 14 | 15 | Edit spserver/openssl/Makefile to specify the path of OpenSSL: 16 | 17 | OPENSSL_INCL = -I 18 | OPENSSL_LIB = -L -lssl -lcrypto 19 | 20 | To build libspopenssl.so, type 21 | 22 | $ cd spserver/openssl 23 | $ make 24 | 25 | This will build all the targets include examples. You can run the 26 | example programs: 27 | 28 | $ ./testhttps 29 | testhttps[12566]: Listen on port [8080] 30 | 31 | You can use the browser ( IE, Firefox, etc. ) to visit: 32 | 33 | https://:8008/ 34 | 35 | bash-2.05a$ ./testechos 36 | testechos[28745]: Listen on port [1995] 37 | 38 | You can use the stelnet to visit: 39 | 40 | ./stelnet 127.0.0.1 1995 41 | 42 | 43 | Enjoy! 44 | 45 | -- stephen liu 46 | 47 | -------------------------------------------------------------------------------- /openssl/demo.crt: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 2 (0x2) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=NO, ST=TEST, L=TEST, O=TEST, OU=TEST, CN=TEST/Email=TEST@TEST.COM 7 | Validity 8 | Not Before: Dec 18 02:06:26 2000 GMT 9 | Not After : Dec 18 02:06:26 2001 GMT 10 | Subject: C=NO, ST=TEST, L=TEST, O=TEST, OU=DEMO, CN=DEMO/Email=TEST@TEST.COM 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (512 bit) 14 | Modulus (512 bit): 15 | 00:c8:46:d3:a7:b5:da:58:b1:5a:08:6b:28:a8:7b: 16 | a5:9b:4a:83:1e:58:4f:0b:18:9e:aa:83:11:27:97: 17 | 24:92:70:0b:47:f4:c8:74:a1:58:92:19:35:88:b3: 18 | 8a:b4:ae:ee:e2:98:5d:bf:d4:53:b8:c6:0c:a1:da: 19 | be:b6:b2:18:f9 20 | Exponent: 65537 (0x10001) 21 | X509v3 extensions: 22 | X509v3 Basic Constraints: 23 | CA:FALSE 24 | Netscape Comment: 25 | OpenSSL Generated Certificate 26 | X509v3 Subject Key Identifier: 27 | 64:2B:31:23:69:F6:49:10:96:EB:BB:5E:91:F2:12:54:37:E6:B3:6B 28 | X509v3 Authority Key Identifier: 29 | keyid:BA:E8:35:48:75:8B:37:A9:77:48:D5:7A:B3:AB:34:C2:41:7C:FF:0E 30 | DirName:/C=NO/ST=TEST/L=TEST/O=TEST/OU=TEST/CN=TEST/Email=TEST@TEST.COM 31 | serial:00 32 | 33 | Signature Algorithm: md5WithRSAEncryption 34 | c0:36:98:cd:32:2d:65:59:60:a9:c9:ca:fa:ba:d8:d6:b1:89: 35 | 16:8b:ae:a5:6f:ea:c3:a0:b1:55:27:0b:04:42:a2:2f:33:39: 36 | fc:46:79:5d:63:33:bf:a7:b2:32:01:a7:17:13:6b:c6:67:2b: 37 | ee:ee:37:3e:64:e4:bb:5d:e9:28:5b:1b:46:33:3d:c1:27:fb: 38 | 8c:ff:ef:e5:49:22:18:e7:6a:03:4c:80:67:45:41:7c:48:e2: 39 | a8:a4:d4:7e:18:09:1d:2d:ab:bd:f0:97:ac:ba:5a:28:46:51: 40 | a0:d3:80:b2:83:70:d4:9a:a6:d0:5f:46:77:43:0e:aa:25:d3: 41 | 19:3c 42 | test haha 43 | -----BEGIN CERTIFICATE----- 44 | MIIDHTCCAoagAwIBAgIBAjANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 45 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 46 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 47 | RVNULkNPTTAeFw0wMDEyMTgwMjA2MjZaFw0wMTEyMTgwMjA2MjZaMHYxCzAJBgNV 48 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 49 | RVNUMQ0wCwYDVQQLEwRERU1PMQ0wCwYDVQQDEwRERU1PMRwwGgYJKoZIhvcNAQkB 50 | Fg1URVNUQFRFU1QuQ09NMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMhG06e12lix 51 | WghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHShWJIZNYizirSu7uKYXb/UU7jG 52 | DKHavrayGPkCAwEAAaOB/jCB+zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P 53 | cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUZCsxI2n2SRCW 54 | 67tekfISVDfms2swgaAGA1UdIwSBmDCBlYAUuug1SHWLN6l3SNV6s6s0wkF8/w6h 55 | eqR4MHYxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNU 56 | MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRww 57 | GgYJKoZIhvcNAQkBFg1URVNUQFRFU1QuQ09NggEAMA0GCSqGSIb3DQEBBAUAA4GB 58 | AMA2mM0yLWVZYKnJyvq62NaxiRaLrqVv6sOgsVUnCwRCoi8zOfxGeV1jM7+nsjIB 59 | pxcTa8ZnK+7uNz5k5Ltd6ShbG0YzPcEn+4z/7+VJIhjnagNMgGdFQXxI4qik1H4Y 60 | CR0tq73wl6y6WihGUaDTgLKDcNSaptBfRndDDqol0xk8 61 | -----END CERTIFICATE----- 62 | -------------------------------------------------------------------------------- /openssl/demo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIBOgIBAAJBAMhG06e12lixWghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHSh 3 | WJIZNYizirSu7uKYXb/UU7jGDKHavrayGPkCAwEAAQJAMXKzTWQr/dwEA7IZfsfQ 4 | kq/qAbMCCRZSDn1/3cuGfxT0Vd/gIXLP+yXdEC1jW1LJoBIhWQLnZHEwyKAS6OIz 5 | 0QIhAP4U3GC+SHfJ27PSGv+hjXp47QNbvvmL5T+SXqqHjqgVAiEAycn2FtiNmkzW 6 | ttLkfdZL609c49d+ac0OiTkMfBTbolUCIA9HZ901dBwn+ls85jy7FUvpG6+ZA8nz 7 | 3KxO+/xbPHvlAiB78tJ2tg5E+W3qXyB7K2b244jrazL7SjnjkGda0HUZAQIhAJVp 8 | ms+n0W3jGqEqUntQFbAfjnUo5FIZCjbiz4glt3Do 9 | -----END RSA PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /openssl/democa.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAp+gAwIBAgIBADANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 3 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 4 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 5 | RVNULkNPTTAeFw0wMDEyMTQwNjE2MjRaFw0wMTEyMTQwNjE2MjRaMHYxCzAJBgNV 6 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 7 | RVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRwwGgYJKoZIhvcNAQkB 8 | Fg1URVNUQFRFU1QuQ09NMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZfu/c 9 | MfHECMJDd94P0xnoKaVvSx1sR6ZUOhoExEmlOLN3vGHingNqeuhHWhfrEV3TuCJU 10 | JKuzxG/63PO1nRKl74j/14t0MRk3Mfu9xJN4VLwxsEy1v46MgAqwKk/nad7xd9kl 11 | +LPfsy2dOYGhhsO/HL2FZ3M+yPlAXQmIIcwciwIDAQABo4HTMIHQMB0GA1UdDgQW 12 | BBS66DVIdYs3qXdI1XqzqzTCQXz/DjCBoAYDVR0jBIGYMIGVgBS66DVIdYs3qXdI 13 | 1XqzqzTCQXz/DqF6pHgwdjELMAkGA1UEBhMCTk8xDTALBgNVBAgTBFRFU1QxDTAL 14 | BgNVBAcTBFRFU1QxDTALBgNVBAoTBFRFU1QxDTALBgNVBAsTBFRFU1QxDTALBgNV 15 | BAMTBFRFU1QxHDAaBgkqhkiG9w0BCQEWDVRFU1RAVEVTVC5DT02CAQAwDAYDVR0T 16 | BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQCFth61VGXHwzhy2zX7gDSSmut2RSYg 17 | 4M0a1pNkkFZjHm4Z4KN9NJQjOgBFrm1tyg+kp9eI/yY0ug4LEZ9mIVudVAluf6wV 18 | edlnf5Fs28OB/vBUR7Vew+5UET5bC3d1Etnu/h1nDLkFiM0fv2bOPkkMCXzeI08G 19 | hz7yss+W7/R7Iw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /openssl/spopenssl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spopenssl_hpp__ 7 | #define __spopenssl_hpp__ 8 | 9 | #include "spiochannel.hpp" 10 | 11 | typedef struct ssl_st SSL; 12 | typedef struct ssl_ctx_st SSL_CTX; 13 | 14 | class SP_OpensslChannel : public SP_IOChannel { 15 | public: 16 | SP_OpensslChannel( SSL_CTX * ctx ); 17 | virtual ~SP_OpensslChannel(); 18 | 19 | virtual int init( int fd ); 20 | 21 | virtual int receive( SP_Session * session ); 22 | 23 | private: 24 | virtual int write_vec( struct iovec * vector, int count ); 25 | 26 | SSL_CTX * mCtx; 27 | SSL * mSsl; 28 | }; 29 | 30 | class SP_OpensslChannelFactory : public SP_IOChannelFactory { 31 | public: 32 | SP_OpensslChannelFactory(); 33 | virtual ~SP_OpensslChannelFactory(); 34 | 35 | virtual SP_IOChannel * create() const; 36 | 37 | int init( const char * certFile, const char * keyFile ); 38 | 39 | private: 40 | SSL_CTX * mCtx; 41 | }; 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /openssl/stelnet: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec openssl s_client -connect $1:$2 -crlf -CApath democa.crt 4 | -------------------------------------------------------------------------------- /openssl/testechos.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spmsgdecoder.hpp" 14 | #include "spbuffer.hpp" 15 | 16 | #include "spserver.hpp" 17 | #include "sphandler.hpp" 18 | #include "spresponse.hpp" 19 | #include "sprequest.hpp" 20 | #include "spopenssl.hpp" 21 | #include "sputils.hpp" 22 | 23 | class SP_EchoHandler : public SP_Handler { 24 | public: 25 | SP_EchoHandler(){} 26 | virtual ~SP_EchoHandler(){} 27 | 28 | // return -1 : terminate session, 0 : continue 29 | virtual int start( SP_Request * request, SP_Response * response ) { 30 | request->setMsgDecoder( new SP_MultiLineMsgDecoder() ); 31 | response->getReply()->getMsg()->append( 32 | "Welcome to line echo server, enter 'quit' to quit.\r\n" ); 33 | 34 | return 0; 35 | } 36 | 37 | // return -1 : terminate session, 0 : continue 38 | virtual int handle( SP_Request * request, SP_Response * response ) { 39 | SP_MultiLineMsgDecoder * decoder = (SP_MultiLineMsgDecoder*)request->getMsgDecoder(); 40 | SP_CircleQueue * queue = decoder->getQueue(); 41 | 42 | int ret = 0; 43 | for( ; NULL != queue->top(); ) { 44 | char * line = (char*)queue->pop(); 45 | 46 | if( 0 != strcasecmp( line, "quit" ) ) { 47 | response->getReply()->getMsg()->append( line ); 48 | response->getReply()->getMsg()->append( "\r\n" ); 49 | } else { 50 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 51 | ret = -1; 52 | } 53 | 54 | free( line ); 55 | } 56 | 57 | return ret; 58 | } 59 | 60 | virtual void error( SP_Response * response ) {} 61 | 62 | virtual void timeout( SP_Response * response ) {} 63 | 64 | virtual void close() {} 65 | }; 66 | 67 | class SP_EchoHandlerFactory : public SP_HandlerFactory { 68 | public: 69 | SP_EchoHandlerFactory() {} 70 | virtual ~SP_EchoHandlerFactory() {} 71 | 72 | virtual SP_Handler * create() const { 73 | return new SP_EchoHandler(); 74 | } 75 | }; 76 | 77 | //--------------------------------------------------------- 78 | 79 | int main( int argc, char * argv[] ) 80 | { 81 | #ifdef LOG_PERROR 82 | openlog( "testechos", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 83 | #else 84 | openlog( "testechos", LOG_CONS | LOG_PID, LOG_USER ); 85 | #endif 86 | 87 | int port = 1995; 88 | 89 | SP_Server server( "", port, new SP_EchoHandlerFactory() ); 90 | 91 | SP_OpensslChannelFactory * opensslFactory = new SP_OpensslChannelFactory(); 92 | opensslFactory->init( "demo.crt", "demo.key" ); 93 | server.setIOChannelFactory( opensslFactory ); 94 | 95 | server.runForever(); 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /openssl/testhttps.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "sphttp.hpp" 15 | #include "sphttpmsg.hpp" 16 | #include "spserver.hpp" 17 | #include "splfserver.hpp" 18 | #include "spopenssl.hpp" 19 | 20 | class SP_HttpEchoHandler : public SP_HttpHandler { 21 | public: 22 | SP_HttpEchoHandler(){} 23 | virtual ~SP_HttpEchoHandler(){} 24 | 25 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) { 26 | response->setStatusCode( 200 ); 27 | response->appendContent( "" 28 | "Welcome to simple http" 29 | "" ); 30 | 31 | char buffer[ 512 ] = { 0 }; 32 | snprintf( buffer, sizeof( buffer ), 33 | "

The requested URI is : %s.

", request->getURI() ); 34 | response->appendContent( buffer ); 35 | 36 | snprintf( buffer, sizeof( buffer ), 37 | "

Client IP is : %s.

", request->getClientIP() ); 38 | response->appendContent( buffer ); 39 | 40 | for( int i = 0; i < request->getParamCount(); i++ ) { 41 | snprintf( buffer, sizeof( buffer ), 42 | "

Param - %s = %s

", request->getParamName( i ), request->getParamValue( i ) ); 43 | response->appendContent( buffer ); 44 | } 45 | 46 | for( int i = 0; i < request->getHeaderCount(); i++ ) { 47 | snprintf( buffer, sizeof( buffer ), 48 | "

Header - %s: %s

", request->getHeaderName( i ), request->getHeaderValue( i ) ); 49 | response->appendContent( buffer ); 50 | } 51 | 52 | if( NULL != request->getContent() ) { 53 | response->appendContent( "

" ); 54 | response->appendContent( request->getContent(), request->getContentLength() ); 55 | response->appendContent( "

" ); 56 | } 57 | 58 | response->appendContent( "\n" ); 59 | } 60 | }; 61 | 62 | class SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory { 63 | public: 64 | SP_HttpEchoHandlerFactory(){} 65 | virtual ~SP_HttpEchoHandlerFactory(){} 66 | 67 | virtual SP_HttpHandler * create() const { 68 | return new SP_HttpEchoHandler(); 69 | } 70 | }; 71 | 72 | int main( int argc, char * argv[] ) 73 | { 74 | int port = 8080, maxThreads = 10; 75 | const char * serverType = "hahs"; 76 | 77 | extern char *optarg ; 78 | int c ; 79 | 80 | while( ( c = getopt ( argc, argv, "p:t:s:v" )) != EOF ) { 81 | switch ( c ) { 82 | case 'p' : 83 | port = atoi( optarg ); 84 | break; 85 | case 't': 86 | maxThreads = atoi( optarg ); 87 | break; 88 | case 's': 89 | serverType = optarg; 90 | break; 91 | case '?' : 92 | case 'v' : 93 | printf( "Usage: %s [-p ] [-t ] [-s ]\n", argv[0] ); 94 | exit( 0 ); 95 | } 96 | } 97 | 98 | #ifdef LOG_PERROR 99 | openlog( "testhttps", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 100 | #else 101 | openlog( "testhttps", LOG_CONS | LOG_PID, LOG_USER ); 102 | #endif 103 | 104 | SP_OpensslChannelFactory * opensslFactory = new SP_OpensslChannelFactory(); 105 | opensslFactory->init( "demo.crt", "demo.key" ); 106 | 107 | if( 0 == strcasecmp( serverType, "hahs" ) ) { 108 | SP_Server server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 109 | 110 | server.setTimeout( 60 ); 111 | server.setMaxThreads( maxThreads ); 112 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 113 | server.setIOChannelFactory( opensslFactory ); 114 | 115 | server.runForever(); 116 | } else { 117 | SP_LFServer server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 118 | 119 | server.setTimeout( 60 ); 120 | server.setMaxThreads( maxThreads ); 121 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 122 | server.setIOChannelFactory( opensslFactory ); 123 | 124 | server.runForever(); 125 | } 126 | 127 | closelog(); 128 | 129 | return 0; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /openssl/testiocphttps.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spporting.hpp" 14 | 15 | #include "sphttp.hpp" 16 | #include "sphttpmsg.hpp" 17 | #include "spiocpserver.hpp" 18 | #include "spopenssl.hpp" 19 | #include "spgetopt.h" 20 | 21 | class SP_HttpEchoHandler : public SP_HttpHandler { 22 | public: 23 | SP_HttpEchoHandler(){} 24 | virtual ~SP_HttpEchoHandler(){} 25 | 26 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) { 27 | response->setStatusCode( 200 ); 28 | response->appendContent( "" 29 | "Welcome to simple http" 30 | "" ); 31 | 32 | char buffer[ 512 ] = { 0 }; 33 | snprintf( buffer, sizeof( buffer ), 34 | "

The requested URI is : %s.

", request->getURI() ); 35 | response->appendContent( buffer ); 36 | 37 | snprintf( buffer, sizeof( buffer ), 38 | "

Client IP is : %s.

", request->getClientIP() ); 39 | response->appendContent( buffer ); 40 | 41 | int i = 0; 42 | 43 | for( i = 0; i < request->getParamCount(); i++ ) { 44 | snprintf( buffer, sizeof( buffer ), 45 | "

Param - %s = %s

", request->getParamName( i ), request->getParamValue( i ) ); 46 | response->appendContent( buffer ); 47 | } 48 | 49 | for( i = 0; i < request->getHeaderCount(); i++ ) { 50 | snprintf( buffer, sizeof( buffer ), 51 | "

Header - %s: %s

", request->getHeaderName( i ), request->getHeaderValue( i ) ); 52 | response->appendContent( buffer ); 53 | } 54 | 55 | if( NULL != request->getContent() ) { 56 | response->appendContent( "

" ); 57 | response->appendContent( request->getContent(), request->getContentLength() ); 58 | response->appendContent( "

" ); 59 | } 60 | 61 | response->appendContent( "\n" ); 62 | } 63 | }; 64 | 65 | class SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory { 66 | public: 67 | SP_HttpEchoHandlerFactory(){} 68 | virtual ~SP_HttpEchoHandlerFactory(){} 69 | 70 | virtual SP_HttpHandler * create() const { 71 | return new SP_HttpEchoHandler(); 72 | } 73 | }; 74 | 75 | void sp_getbasepath( char * path, int size ) 76 | { 77 | spwin32_getexefile( GetCurrentProcessId(), path, size ); 78 | 79 | char * pos = strrchr( path, '\\' ); 80 | if( NULL != pos ) *pos = '\0'; 81 | } 82 | 83 | int main( int argc, char * argv[] ) 84 | { 85 | int port = 8080, maxThreads = 10; 86 | 87 | extern char *optarg ; 88 | int c ; 89 | 90 | while( ( c = getopt ( argc, argv, "p:t:v" )) != EOF ) { 91 | switch ( c ) { 92 | case 'p' : 93 | port = atoi( optarg ); 94 | break; 95 | case 't': 96 | maxThreads = atoi( optarg ); 97 | break; 98 | case '?' : 99 | case 'v' : 100 | printf( "Usage: %s [-p ] [-t ]\n", argv[0] ); 101 | exit( 0 ); 102 | } 103 | } 104 | 105 | if( 0 != sp_initsock() ) assert( 0 ); 106 | 107 | char basePath[ 256 ] = { 0 }, crtPath[ 256 ] = { 0 }, keyPath[ 256 ] = { 0 }; 108 | sp_getbasepath( basePath, sizeof( basePath ) ); 109 | snprintf( crtPath, sizeof( crtPath ), "%s\\..\\..\\..\\openssl\\demo.crt", basePath ); 110 | snprintf( keyPath, sizeof( keyPath ), "%s\\..\\..\\..\\openssl\\demo.key", basePath ); 111 | 112 | SP_OpensslChannelFactory * opensslFactory = new SP_OpensslChannelFactory(); 113 | if( 0 != opensslFactory->init( crtPath, keyPath ) ) assert( 0 ); 114 | 115 | SP_IocpServer server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 116 | 117 | server.setTimeout( 60 ); 118 | server.setMaxThreads( maxThreads ); 119 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 120 | server.setIOChannelFactory( opensslFactory ); 121 | 122 | server.runForever(); 123 | 124 | return 0; 125 | } 126 | 127 | -------------------------------------------------------------------------------- /spserver/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | LIBEVENT_INCL = -I$(HOME)/libevent/ 15 | LIBEVENT_LIB = -L$(HOME)/libevent -levent -lrt 16 | 17 | CFLAGS += $(LIBEVENT_INCL) 18 | LDFLAGS += $(LIBEVENT_LIB) 19 | 20 | #-------------------------------------------------------------------- 21 | 22 | LIBOBJS = sputils.o spioutils.o spiochannel.o \ 23 | spthreadpool.o event_msgqueue.o spbuffer.o sphandler.o \ 24 | spmsgblock.o spmsgdecoder.o spresponse.o sprequest.o \ 25 | spexecutor.o spsession.o speventcb.o spserver.o \ 26 | spdispatcher.o splfserver.o \ 27 | sphttpmsg.o sphttp.o spsmtp.o 28 | 29 | TARGET = libspserver.so libspserver.a \ 30 | testecho testthreadpool testsmtp testchat teststress testhttp \ 31 | testhttp_d testhttpmsg testdispatcher testchat_d testunp 32 | 33 | #-------------------------------------------------------------------- 34 | 35 | all: $(TARGET) 36 | 37 | libspserver.so: $(LIBOBJS) 38 | $(LINKER) $(SOFLAGS) $^ -o $@ 39 | 40 | libspserver.a: $(LIBOBJS) 41 | $(AR) $@ $^ 42 | 43 | testthreadpool: testthreadpool.o 44 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 45 | 46 | testsmtp: testsmtp.o 47 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 48 | 49 | testchat: testchat.o 50 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 51 | 52 | teststress: teststress.o 53 | $(LINKER) $^ -L. -levent $(LDFLAGS) -o $@ 54 | 55 | testecho: testecho.o 56 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 57 | 58 | testhttp: testhttp.o 59 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 60 | 61 | testhttp_d: testhttp_d.o 62 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 63 | 64 | testhttpmsg: sputils.o sphttpmsg.o testhttpmsg.o 65 | $(LINKER) $^ $(LDFLAGS) -o $@ 66 | 67 | testdispatcher: testdispatcher.o 68 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 69 | 70 | testchat_d: testchat_d.o 71 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 72 | 73 | testunp: testunp.o 74 | $(LINKER) $^ -L. -lspserver $(LDFLAGS) -o $@ 75 | 76 | clean: 77 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 78 | 79 | #-------------------------------------------------------------------- 80 | 81 | # make rule 82 | %.o : %.c 83 | $(CC) $(CFLAGS) -c $^ -o $@ 84 | 85 | %.o : %.cpp 86 | $(CC) $(CFLAGS) -c $^ -o $@ 87 | 88 | -------------------------------------------------------------------------------- /spserver/Makefile.darwin: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC -fexceptions 7 | SOFLAGS = -dynamiclib -flat_namespace -undefined suppress 8 | LDFLAGS = -lstdc++ 9 | 10 | LINKER = g++ 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | 15 | LIBEVENT_INCL = -I$(HOME)/libevent/ 16 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 17 | 18 | CFLAGS += $(LIBEVENT_INCL) 19 | LDFLAGS += $(LIBEVENT_LIB) -lpthread -lresolv 20 | 21 | #-------------------------------------------------------------------- 22 | 23 | LIBOBJS = sputils.o spioutils.o spiochannel.o \ 24 | spthreadpool.o event_msgqueue.o spbuffer.o sphandler.o \ 25 | spmsgblock.o spmsgdecoder.o spresponse.o sprequest.o \ 26 | spexecutor.o spsession.o speventcb.o spserver.o \ 27 | spdispatcher.o splfserver.o \ 28 | sphttpmsg.o sphttp.o spsmtp.o 29 | 30 | TARGET = libspserver.dylib \ 31 | testecho testchat teststress testhttp 32 | 33 | #-------------------------------------------------------------------- 34 | 35 | all: $(TARGET) 36 | 37 | libspserver.dylib: $(LIBOBJS) 38 | $(LINKER) $(SOFLAGS) $^ -o $@ 39 | 40 | teststress: teststress.o 41 | $(LINKER) $(LDFLAGS) $^ -L. -levent -o $@ 42 | 43 | testecho: testecho.o 44 | $(LINKER) $(LDFLAGS) $^ -L. libspserver.dylib -o $@ 45 | 46 | testchat: testchat.o 47 | $(LINKER) $(LDFLAGS) $^ -L. libspserver.dylib -o $@ 48 | 49 | testhttp: testhttp.o 50 | $(LINKER) $(LDFLAGS) $^ -L. libspserver.dylib -o $@ 51 | 52 | clean: 53 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 54 | 55 | #-------------------------------------------------------------------- 56 | 57 | # make rule 58 | %.o : %.c 59 | $(CC) $(CFLAGS) -c $^ -o $@ 60 | 61 | %.o : %.cpp 62 | $(CC) $(CFLAGS) -c $^ -o $@ 63 | 64 | -------------------------------------------------------------------------------- /spserver/README: -------------------------------------------------------------------------------- 1 | spserver README 2 | 3 | 1.Introduction 4 | 5 | spserver is a TCP server framework library written in C++ based on libevent. 6 | 7 | spserver implements the Half-Sync/Half-Async and the Leader/Follower patterns. 8 | 9 | More detail about the Half-Sync/Half-Async and Leader/Follower patterns: 10 | 11 | http://www.cs.wustl.edu/~schmidt/PDF/HS-HA.pdf 12 | http://www.cs.wustl.edu/~schmidt/PDF/lf.pdf 13 | 14 | Code description: 15 | 16 | SP_Server class implements the Half-Sync/Half-Async pattern. 17 | 18 | SP_Server, SP_EventCallback, SP_Session, SP_Request(SP_MsgDecoder), SP_Response(SP_Message) 19 | The asynchronous layer, which receives the asynchronous requests 20 | 21 | SP_EventArg::mInputResultQueue, SP_EventArg::mOutputResultQueue 22 | The queueing layer, which buffers the requests 23 | 24 | SP_Executor, SP_ThreadPool, SP_Handler 25 | The synchronous layer, which contains several threads of control blocked 26 | on the queueing layer 27 | 28 | SP_LFServer class implements the Leader/Follower pattern. 29 | 30 | The spserver code was developed under Linux, but has also been tested under Solaris. 31 | 32 | You can get the code from the spserver home page: 33 | 34 | http://code.google.com/p/spserver/ 35 | 36 | 2.Building 37 | 38 | Before building spserver, libevent must been installed. Test with libevent 1.1 and 1.2. 39 | 40 | You can donwload libevent from its home page: 41 | 42 | http://www.monkey.org/~provos/libevent/ 43 | 44 | Edit spserver/Makefile to specify the path of libevent: 45 | 46 | LIBEVENT_INCL = -I 47 | LIBEVENT_LIB = -L -levent 48 | 49 | To build libspserver.so, type 50 | 51 | $ cd spserver 52 | $ make 53 | 54 | This will build all the targets include examples. You can run the 55 | example programs: 56 | 57 | $ ./testsmtp 58 | [msg] This server is listening on port [1025]. 59 | 60 | Open another console, use telnet to test: 61 | 62 | $ telnet 127.0.0.1 1025 63 | Trying 127.0.0.1... 64 | Connected to 127.0.0.1. 65 | Escape character is '^]'. 66 | 67 | 220 SMTP Server Ready 68 | helo abc 69 | 250 ok. 70 | mail from: 71 | 250 sender ok. 72 | rcpt to: 73 | 250 recipient ok. 74 | data 75 | 354 Start mail input; end with . 76 | From: abc@abc.com 77 | To: foo@bar.com 78 | Subject: test 79 | 80 | test 81 | . 82 | 250 Requested mail action okay, completed. 83 | quit 84 | 221 Closing connection. Good bye. 85 | Connection closed by foreign host. 86 | 87 | 3.Credits 88 | 89 | Special thanks go to Andrew Danforth, who provides a good solution to 90 | use libevent in multithreaded environment. 91 | 92 | Any and all comments are appreciated. 93 | 94 | Enjoy! 95 | 96 | -- stephen liu 97 | 98 | -------------------------------------------------------------------------------- /spserver/event_msgqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * event_msgqueue.h 3 | * 4 | * Libevent threaded message passing primitives header 5 | * 6 | * Andrew Danforth , October 2006 7 | * 8 | * Copyright (c) Andrew Danforth, 2006 9 | * 10 | */ 11 | 12 | #ifndef _EVENT_MSGQUEUE_H_ 13 | #define _EVENT_MSGQUEUE_H_ 14 | 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | struct event_msgqueue; 22 | 23 | struct event_msgqueue *msgqueue_new(struct event_base *, unsigned int, void (*)(void *, void *), void *); 24 | int msgqueue_push(struct event_msgqueue *, void *); 25 | unsigned int msgqueue_length(struct event_msgqueue *); 26 | void msgqueue_destroy(struct event_msgqueue*); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /spserver/spbuffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "spporting.hpp" 12 | 13 | #include "spbuffer.hpp" 14 | 15 | #ifdef WIN32 16 | 17 | #include "spwin32buffer.hpp" 18 | 19 | #else 20 | 21 | #include "event.h" 22 | 23 | #define sp_evbuffer_new evbuffer_new 24 | #define sp_evbuffer_free evbuffer_free 25 | #define sp_evbuffer_add evbuffer_add 26 | #define sp_evbuffer_drain evbuffer_drain 27 | #define sp_evbuffer_expand evbuffer_expand 28 | #define sp_evbuffer_remove evbuffer_remove 29 | #define sp_evbuffer_readline evbuffer_readline 30 | #define sp_evbuffer_add_vprintf evbuffer_add_vprintf 31 | 32 | #endif 33 | 34 | SP_Buffer :: SP_Buffer() 35 | { 36 | mBuffer = sp_evbuffer_new(); 37 | } 38 | 39 | SP_Buffer :: ~SP_Buffer() 40 | { 41 | sp_evbuffer_free( mBuffer ); 42 | mBuffer = NULL; 43 | } 44 | 45 | int SP_Buffer :: append( const void * buffer, int len ) 46 | { 47 | len = len <= 0 ? strlen( (char*)buffer ) : len; 48 | 49 | return sp_evbuffer_add( mBuffer, (void*)buffer, len ); 50 | } 51 | 52 | int SP_Buffer :: append( const SP_Buffer * buffer ) 53 | { 54 | if( buffer->getSize() > 0 ) { 55 | return append( buffer->getBuffer(), buffer->getSize() ); 56 | } else { 57 | return 0; 58 | } 59 | } 60 | 61 | int SP_Buffer :: printf( const char *fmt, ... ) 62 | { 63 | int ret = 0; 64 | 65 | if( NULL != strchr( fmt, '%' ) ) { 66 | va_list args; 67 | va_start(args, fmt); 68 | ret = sp_evbuffer_add_vprintf( mBuffer, fmt, args ); 69 | va_end(args); 70 | } else { 71 | ret = append( fmt ); 72 | } 73 | 74 | return ret; 75 | } 76 | 77 | void SP_Buffer :: erase( int len ) 78 | { 79 | sp_evbuffer_drain( mBuffer, len ); 80 | } 81 | 82 | void SP_Buffer :: reset() 83 | { 84 | erase( getSize() ); 85 | } 86 | 87 | int SP_Buffer :: truncate( int len ) 88 | { 89 | if( len < (int)getSize() ) { 90 | EVBUFFER_LENGTH( mBuffer ) = len; 91 | return 0; 92 | } 93 | 94 | return -1; 95 | } 96 | 97 | void SP_Buffer :: reserve( int len ) 98 | { 99 | sp_evbuffer_expand( mBuffer, len - getSize() ); 100 | } 101 | 102 | int SP_Buffer :: getCapacity() 103 | { 104 | return mBuffer->totallen; 105 | } 106 | 107 | const void * SP_Buffer :: getBuffer() const 108 | { 109 | if( NULL != EVBUFFER_DATA( mBuffer ) ) { 110 | sp_evbuffer_expand( mBuffer, 1 ); 111 | ((char*)(EVBUFFER_DATA( mBuffer )))[ getSize() ] = '\0'; 112 | return EVBUFFER_DATA( mBuffer ); 113 | } else { 114 | return ""; 115 | } 116 | } 117 | 118 | const void * SP_Buffer :: getRawBuffer() const 119 | { 120 | return EVBUFFER_DATA( mBuffer ); 121 | } 122 | 123 | size_t SP_Buffer :: getSize() const 124 | { 125 | return EVBUFFER_LENGTH( mBuffer ); 126 | } 127 | 128 | char * SP_Buffer :: getLine() 129 | { 130 | return sp_evbuffer_readline( mBuffer ); 131 | } 132 | 133 | int SP_Buffer :: take( char * buffer, int len ) 134 | { 135 | len = sp_evbuffer_remove( mBuffer, buffer, len - 1); 136 | buffer[ len ] = '\0'; 137 | 138 | return len; 139 | } 140 | 141 | SP_Buffer * SP_Buffer :: take() 142 | { 143 | SP_Buffer * ret = new SP_Buffer(); 144 | 145 | sp_evbuffer_t * tmp = ret->mBuffer; 146 | ret->mBuffer = mBuffer; 147 | mBuffer = tmp; 148 | 149 | return ret; 150 | } 151 | 152 | const void * SP_Buffer :: find( const void * key, size_t len ) 153 | { 154 | //return (void*)evbuffer_find( mBuffer, (u_char*)key, len ); 155 | 156 | sp_evbuffer_t * buffer = mBuffer; 157 | u_char * what = (u_char*)key; 158 | 159 | size_t remain = buffer->off; 160 | u_char *search = buffer->buffer; 161 | u_char *p; 162 | 163 | while (remain >= len) { 164 | if ((p = (u_char*)memchr(search, *what, (remain - len) + 1)) == NULL) 165 | break; 166 | 167 | if (memcmp(p, what, len) == 0) 168 | return (p); 169 | 170 | search = p + 1; 171 | remain = buffer->off - (size_t)(search - buffer->buffer); 172 | } 173 | 174 | return (NULL); 175 | } 176 | 177 | -------------------------------------------------------------------------------- /spserver/spbuffer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spbuffer_hpp__ 8 | #define __spbuffer_hpp__ 9 | 10 | #include 11 | 12 | #ifdef WIN32 13 | typedef struct spwin32buffer sp_evbuffer_t; 14 | #else 15 | typedef struct evbuffer sp_evbuffer_t; 16 | #endif 17 | 18 | struct evbuffer; 19 | 20 | class SP_Buffer { 21 | public: 22 | SP_Buffer(); 23 | ~SP_Buffer(); 24 | 25 | int append( const void * buffer, int len = 0 ); 26 | int append( const SP_Buffer * buffer ); 27 | int printf( const char *fmt, ... ); 28 | 29 | void erase( int len ); 30 | void reset(); 31 | int truncate( int len ); 32 | void reserve( int len ); 33 | int getCapacity(); 34 | 35 | const void * getBuffer() const; 36 | const void * getRawBuffer() const; 37 | size_t getSize() const; 38 | int take( char * buffer, int len ); 39 | 40 | char * getLine(); 41 | const void * find( const void * key, size_t len ); 42 | 43 | SP_Buffer * take(); 44 | 45 | private: 46 | sp_evbuffer_t * mBuffer; 47 | 48 | friend class SP_IOChannel; 49 | friend class SP_IocpEventCallback; 50 | }; 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /spserver/spdispatcher.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spdispatcher_hpp__ 7 | #define __spdispatcher_hpp__ 8 | 9 | #include "spporting.hpp" 10 | #include "spthread.hpp" 11 | 12 | class SP_CompletionHandler; 13 | class SP_Handler; 14 | class SP_Message; 15 | class SP_BlockingQueue; 16 | class SP_TimerHandler; 17 | class SP_IOChannel; 18 | class SP_Response; 19 | 20 | class SP_EventArg; 21 | 22 | class SP_Dispatcher { 23 | public: 24 | SP_Dispatcher( SP_CompletionHandler * completionHandler, int maxThreads = 64 ); 25 | ~SP_Dispatcher(); 26 | 27 | void setTimeout( int timeout ); 28 | 29 | int getSessionCount(); 30 | int getReqQueueLength(); 31 | 32 | void shutdown(); 33 | int isRunning(); 34 | 35 | /** 36 | * @brief create a thread to run event loop 37 | * @return 0 : OK, -1 : Fail, cannot create thread 38 | */ 39 | int dispatch(); 40 | 41 | /** 42 | * @brief register a fd into dispatcher 43 | * @param needStart : 1 - call handler::start, 0 - don't call handler::start 44 | * @return 0 : OK, -1 : Fail, invalid fd 45 | * @note handler will be deleted by dispatcher when the session is close 46 | */ 47 | int push( int fd, SP_Handler * handler, int needStart = 1 ); 48 | 49 | int push( int fd, SP_Handler * handler, SP_IOChannel * ioChannel, int needStart = 1 ); 50 | 51 | /** 52 | * @brief register a timer into dispatcher 53 | * @param timeout : the interval for the timer 54 | * @note handler will be deleted by dispatcher when the timer is terminated 55 | */ 56 | int push( const struct timeval * timeout, SP_TimerHandler * handler ); 57 | 58 | /** 59 | * @brief push a response 60 | */ 61 | int push( SP_Response * response ); 62 | 63 | private: 64 | int mIsShutdown; 65 | int mIsRunning; 66 | int mMaxThreads; 67 | 68 | SP_EventArg * mEventArg; 69 | SP_CompletionHandler * mCompletionHandler; 70 | 71 | void * mPushQueue; 72 | 73 | int start(); 74 | 75 | static sp_thread_result_t SP_THREAD_CALL eventLoop( void * arg ); 76 | 77 | static void onPush( void * queueData, void * arg ); 78 | 79 | static void outputCompleted( void * arg ); 80 | 81 | static void onTimer( int, short, void * arg ); 82 | static void timer( void * arg ); 83 | }; 84 | 85 | #endif 86 | 87 | -------------------------------------------------------------------------------- /spserver/speventcb.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __speventcb_hpp__ 7 | #define __speventcb_hpp__ 8 | 9 | class SP_HandlerFactory; 10 | class SP_SessionManager; 11 | class SP_Session; 12 | class SP_BlockingQueue; 13 | class SP_Message; 14 | class SP_IOChannelFactory; 15 | 16 | struct event_base; 17 | typedef struct tagSP_Sid SP_Sid_t; 18 | 19 | class SP_EventArg { 20 | public: 21 | SP_EventArg( int timeout ); 22 | ~SP_EventArg(); 23 | 24 | struct event_base * getEventBase() const; 25 | void * getResponseQueue() const; 26 | SP_BlockingQueue * getInputResultQueue() const; 27 | SP_BlockingQueue * getOutputResultQueue() const; 28 | SP_SessionManager * getSessionManager() const; 29 | 30 | void setTimeout( int timeout ); 31 | int getTimeout() const; 32 | 33 | private: 34 | struct event_base * mEventBase; 35 | void * mResponseQueue; 36 | 37 | SP_BlockingQueue * mInputResultQueue; 38 | SP_BlockingQueue * mOutputResultQueue; 39 | 40 | SP_SessionManager * mSessionManager; 41 | 42 | int mTimeout; 43 | }; 44 | 45 | typedef struct tagSP_AcceptArg { 46 | SP_EventArg * mEventArg; 47 | 48 | SP_HandlerFactory * mHandlerFactory; 49 | SP_IOChannelFactory * mIOChannelFactory; 50 | int mReqQueueSize; 51 | int mMaxConnections; 52 | char * mRefusedMsg; 53 | } SP_AcceptArg_t; 54 | 55 | class SP_EventCallback { 56 | public: 57 | static void onAccept( int fd, short events, void * arg ); 58 | static void onRead( int fd, short events, void * arg ); 59 | static void onWrite( int fd, short events, void * arg ); 60 | 61 | static void onResponse( void * queueData, void * arg ); 62 | 63 | static void addEvent( SP_Session * session, short events, int fd ); 64 | 65 | private: 66 | SP_EventCallback(); 67 | ~SP_EventCallback(); 68 | }; 69 | 70 | class SP_EventHelper { 71 | public: 72 | static void doStart( SP_Session * session ); 73 | static void start( void * arg ); 74 | 75 | static void doWork( SP_Session * session ); 76 | static void worker( void * arg ); 77 | 78 | static void doError( SP_Session * session ); 79 | static void error( void * arg ); 80 | 81 | static void doTimeout( SP_Session * session ); 82 | static void timeout( void * arg ); 83 | 84 | static void doClose( SP_Session * session ); 85 | static void myclose( void * arg ); 86 | 87 | static void doCompletion( SP_EventArg * eventArg, SP_Message * msg ); 88 | 89 | static int isSystemSid( SP_Sid_t * sid ); 90 | 91 | private: 92 | SP_EventHelper(); 93 | ~SP_EventHelper(); 94 | }; 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /spserver/spexecutor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #include 8 | #include 9 | 10 | #include "spporting.hpp" 11 | 12 | #include "spexecutor.hpp" 13 | #include "spthreadpool.hpp" 14 | 15 | #include "sputils.hpp" 16 | 17 | SP_Task :: ~SP_Task() 18 | { 19 | } 20 | 21 | //=================================================================== 22 | 23 | SP_SimpleTask :: SP_SimpleTask( ThreadFunc_t func, void * arg, int deleteAfterRun ) 24 | { 25 | mFunc = func; 26 | mArg = arg; 27 | 28 | mDeleteAfterRun = deleteAfterRun; 29 | } 30 | 31 | SP_SimpleTask :: ~SP_SimpleTask() 32 | { 33 | } 34 | 35 | void SP_SimpleTask :: run() 36 | { 37 | mFunc( mArg ); 38 | 39 | if( mDeleteAfterRun ) delete this; 40 | } 41 | 42 | //=================================================================== 43 | 44 | SP_Executor :: SP_Executor( int maxThreads, const char * tag ) 45 | { 46 | tag = NULL == tag ? "unknown" : tag; 47 | 48 | mThreadPool = new SP_ThreadPool( maxThreads, tag ); 49 | 50 | mQueue = new SP_BlockingQueue(); 51 | 52 | mIsShutdown = 0; 53 | 54 | sp_thread_mutex_init( &mMutex, NULL ); 55 | sp_thread_cond_init( &mCond, NULL ); 56 | 57 | sp_thread_attr_t attr; 58 | sp_thread_attr_init( &attr ); 59 | assert( sp_thread_attr_setstacksize( &attr, 1024 * 1024 ) == 0 ); 60 | sp_thread_attr_setdetachstate( &attr, SP_THREAD_CREATE_DETACHED ); 61 | 62 | sp_thread_t thread; 63 | int ret = sp_thread_create( &thread, &attr, eventLoop, this ); 64 | sp_thread_attr_destroy( &attr ); 65 | if( 0 == ret ) { 66 | sp_syslog( LOG_NOTICE, "[ex@%s] Thread #%ld has been created for executor", tag, thread ); 67 | } else { 68 | sp_syslog( LOG_WARNING, "[ex@%s] Unable to create a thread for executor", tag ); 69 | } 70 | } 71 | 72 | SP_Executor :: ~SP_Executor() 73 | { 74 | shutdown(); 75 | 76 | while( 2 != mIsShutdown ) { 77 | sp_thread_mutex_lock( &mMutex ); 78 | sp_thread_cond_wait( &mCond, &mMutex ); 79 | sp_thread_mutex_unlock( &mMutex ); 80 | } 81 | 82 | sp_thread_mutex_destroy( &mMutex ); 83 | sp_thread_cond_destroy( &mCond); 84 | 85 | delete mThreadPool; 86 | mThreadPool = NULL; 87 | 88 | delete mQueue; 89 | mQueue = NULL; 90 | } 91 | 92 | void SP_Executor :: shutdown() 93 | { 94 | sp_thread_mutex_lock( &mMutex ); 95 | if( 0 == mIsShutdown ) { 96 | mIsShutdown = 1; 97 | 98 | // signal the event loop to wake up 99 | execute( worker, NULL ); 100 | } 101 | sp_thread_mutex_unlock( &mMutex ); 102 | } 103 | 104 | sp_thread_result_t SP_THREAD_CALL SP_Executor :: eventLoop( void * arg ) 105 | { 106 | SP_Executor * executor = ( SP_Executor * )arg; 107 | 108 | while( 0 == executor->mIsShutdown ) { 109 | void * queueData = executor->mQueue->pop(); 110 | 111 | if( executor->mThreadPool->getMaxThreads() > 1 ) { 112 | if( 0 != executor->mThreadPool->dispatch( worker, queueData ) ) { 113 | worker( queueData ); 114 | } 115 | } else { 116 | worker( queueData ); 117 | } 118 | } 119 | 120 | sp_thread_mutex_lock( &executor->mMutex ); 121 | executor->mIsShutdown = 2; 122 | sp_thread_cond_signal( &executor->mCond ); 123 | sp_thread_mutex_unlock( &executor->mMutex ); 124 | 125 | return 0; 126 | } 127 | 128 | void SP_Executor :: worker( void * arg ) 129 | { 130 | if( NULL != arg ) { 131 | SP_Task * task = ( SP_Task * )arg; 132 | task->run(); 133 | } 134 | } 135 | 136 | void SP_Executor :: execute( SP_Task * task ) 137 | { 138 | mQueue->push( task ); 139 | } 140 | 141 | void SP_Executor :: execute( void ( * func ) ( void * ), void * arg ) 142 | { 143 | SP_SimpleTask * task = new SP_SimpleTask( func, arg, 1 ); 144 | execute( task ); 145 | } 146 | 147 | int SP_Executor :: getQueueLength() 148 | { 149 | return mQueue->getLength(); 150 | } 151 | 152 | -------------------------------------------------------------------------------- /spserver/spexecutor.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spexecutor_hpp__ 8 | #define __spexecutor_hpp__ 9 | 10 | #include "spthread.hpp" 11 | 12 | class SP_ThreadPool; 13 | class SP_BlockingQueue; 14 | 15 | class SP_Task { 16 | public: 17 | virtual ~SP_Task(); 18 | virtual void run() = 0; 19 | }; 20 | 21 | class SP_SimpleTask : public SP_Task { 22 | public: 23 | typedef void ( * ThreadFunc_t ) ( void * ); 24 | 25 | SP_SimpleTask( ThreadFunc_t func, void * arg, int deleteAfterRun ); 26 | virtual ~SP_SimpleTask(); 27 | 28 | virtual void run(); 29 | 30 | private: 31 | ThreadFunc_t mFunc; 32 | void * mArg; 33 | 34 | int mDeleteAfterRun; 35 | }; 36 | 37 | class SP_Executor { 38 | public: 39 | SP_Executor( int maxThreads, const char * tag = 0 ); 40 | ~SP_Executor(); 41 | 42 | void execute( SP_Task * task ); 43 | void execute( void ( * func ) ( void * ), void * arg ); 44 | int getQueueLength(); 45 | void shutdown(); 46 | 47 | private: 48 | static void msgQueueCallback( void * queueData, void * arg ); 49 | static void worker( void * arg ); 50 | static sp_thread_result_t SP_THREAD_CALL eventLoop( void * arg ); 51 | 52 | SP_ThreadPool * mThreadPool; 53 | SP_BlockingQueue * mQueue; 54 | 55 | int mIsShutdown; 56 | 57 | sp_thread_mutex_t mMutex; 58 | sp_thread_cond_t mCond; 59 | }; 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /spserver/spgetopt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1987 Regents of the University of California. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #if defined(LIBC_SCCS) && !defined(lint) 35 | static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; 36 | #endif /* LIBC_SCCS and not lint */ 37 | 38 | #include 39 | #include 40 | 41 | /* 42 | * get option letter from argument vector 43 | */ 44 | int opterr = 1, /* if error message should be printed */ 45 | optind = 1, /* index into parent argv vector */ 46 | optopt; /* character checked for validity */ 47 | char *optarg; /* argument associated with option */ 48 | 49 | #define BADCH (int)'?' 50 | #define EMSG "" 51 | 52 | int 53 | getopt(nargc, nargv, ostr) 54 | int nargc; 55 | char **nargv; 56 | char *ostr; 57 | { 58 | static char *place = EMSG; /* option letter processing */ 59 | register char *oli; /* option letter list index */ 60 | char *p; 61 | 62 | if (!*place) { /* update scanning pointer */ 63 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 64 | place = EMSG; 65 | return(EOF); 66 | } 67 | if (place[1] && *++place == '-') { /* found "--" */ 68 | ++optind; 69 | place = EMSG; 70 | return(EOF); 71 | } 72 | } /* option letter okay? */ 73 | if ((optopt = (int)*place++) == (int)':' || 74 | !(oli = strchr(ostr, optopt))) { 75 | /* 76 | * if the user didn't specify '-' as an option, 77 | * assume it means EOF. 78 | */ 79 | if (optopt == (int)'-') 80 | return(EOF); 81 | if (!*place) 82 | ++optind; 83 | if (opterr) { 84 | if (!(p = strrchr(*nargv, '/'))) 85 | p = *nargv; 86 | else 87 | ++p; 88 | (void)fprintf(stderr, "%s: illegal option -- %c\n", 89 | p, optopt); 90 | } 91 | return(BADCH); 92 | } 93 | if (*++oli != ':') { /* don't need argument */ 94 | optarg = NULL; 95 | if (!*place) 96 | ++optind; 97 | } 98 | else { /* need an argument */ 99 | if (*place) /* no white space */ 100 | optarg = place; 101 | else if (nargc <= ++optind) { /* no arg */ 102 | place = EMSG; 103 | if (!(p = strrchr(*nargv, '/'))) 104 | p = *nargv; 105 | else 106 | ++p; 107 | if (opterr) 108 | (void)fprintf(stderr, 109 | "%s: option requires an argument -- %c\n", 110 | p, optopt); 111 | return(BADCH); 112 | } 113 | else /* white space */ 114 | optarg = nargv[optind]; 115 | place = EMSG; 116 | ++optind; 117 | } 118 | return(optopt); /* dump back option letter */ 119 | } 120 | -------------------------------------------------------------------------------- /spserver/spgetopt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spgetopt_h__ 7 | #define __spgetopt_h__ 8 | 9 | #ifdef WIN32 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | extern char *optarg; 16 | extern int optind; 17 | extern int opterr; 18 | extern int optopt; 19 | int getopt(int argc, char* const *argv, const char *optstr); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /spserver/sphandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include "sphandler.hpp" 7 | #include "spresponse.hpp" 8 | 9 | SP_Handler :: ~SP_Handler() 10 | { 11 | } 12 | 13 | //--------------------------------------------------------- 14 | 15 | SP_TimerHandler :: ~SP_TimerHandler() 16 | { 17 | } 18 | 19 | //--------------------------------------------------------- 20 | 21 | SP_CompletionHandler :: ~SP_CompletionHandler() 22 | { 23 | } 24 | 25 | //--------------------------------------------------------- 26 | 27 | SP_DefaultCompletionHandler :: SP_DefaultCompletionHandler() 28 | { 29 | } 30 | 31 | SP_DefaultCompletionHandler :: ~SP_DefaultCompletionHandler() 32 | { 33 | } 34 | 35 | void SP_DefaultCompletionHandler :: completionMessage( SP_Message * msg ) 36 | { 37 | delete msg; 38 | } 39 | 40 | //--------------------------------------------------------- 41 | 42 | SP_HandlerFactory :: ~SP_HandlerFactory() 43 | { 44 | } 45 | 46 | SP_CompletionHandler * SP_HandlerFactory :: createCompletionHandler() const 47 | { 48 | return new SP_DefaultCompletionHandler(); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /spserver/sphandler.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __sphandler_hpp__ 8 | #define __sphandler_hpp__ 9 | 10 | class SP_Buffer; 11 | class SP_Request; 12 | class SP_Response; 13 | class SP_Message; 14 | 15 | struct event; 16 | struct timeval; 17 | 18 | class SP_Handler { 19 | public: 20 | virtual ~SP_Handler(); 21 | 22 | // return -1 : terminate session, 0 : continue 23 | virtual int start( SP_Request * request, SP_Response * response ) = 0; 24 | 25 | // return -1 : terminate session, 0 : continue 26 | virtual int handle( SP_Request * request, SP_Response * response ) = 0; 27 | 28 | virtual void error( SP_Response * response ) = 0; 29 | 30 | virtual void timeout( SP_Response * response ) = 0; 31 | 32 | virtual void close() = 0; 33 | }; 34 | 35 | class SP_TimerHandler { 36 | public: 37 | virtual ~SP_TimerHandler(); 38 | 39 | // return -1 : terminate timer, 0 : continue 40 | virtual int handle( SP_Response * response, struct timeval * timeout ) = 0; 41 | }; 42 | 43 | /** 44 | * @note Asynchronous Completion Token 45 | */ 46 | class SP_CompletionHandler { 47 | public: 48 | virtual ~SP_CompletionHandler(); 49 | 50 | virtual void completionMessage( SP_Message * msg ) = 0; 51 | }; 52 | 53 | class SP_DefaultCompletionHandler : public SP_CompletionHandler { 54 | public: 55 | SP_DefaultCompletionHandler(); 56 | ~SP_DefaultCompletionHandler(); 57 | 58 | virtual void completionMessage( SP_Message * msg ); 59 | }; 60 | 61 | class SP_HandlerFactory { 62 | public: 63 | virtual ~SP_HandlerFactory(); 64 | 65 | virtual SP_Handler * create() const = 0; 66 | 67 | virtual SP_CompletionHandler * createCompletionHandler() const; 68 | }; 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /spserver/sphttp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __sphttp_hpp__ 7 | #define __sphttp_hpp__ 8 | 9 | #include "sphandler.hpp" 10 | #include "spmsgdecoder.hpp" 11 | 12 | class SP_HttpRequest; 13 | class SP_HttpResponse; 14 | class SP_HttpMsgParser; 15 | 16 | class SP_HttpHandler { 17 | public: 18 | virtual ~SP_HttpHandler(); 19 | 20 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) = 0; 21 | 22 | virtual void error(); 23 | 24 | virtual void timeout(); 25 | }; 26 | 27 | class SP_HttpHandlerFactory { 28 | public: 29 | virtual ~SP_HttpHandlerFactory(); 30 | 31 | virtual SP_HttpHandler * create() const = 0; 32 | }; 33 | 34 | class SP_HttpHandlerAdapterFactory : public SP_HandlerFactory { 35 | public: 36 | SP_HttpHandlerAdapterFactory( SP_HttpHandlerFactory * factory ); 37 | 38 | virtual ~SP_HttpHandlerAdapterFactory(); 39 | 40 | virtual SP_Handler * create() const; 41 | 42 | private: 43 | SP_HttpHandlerFactory * mFactory; 44 | }; 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /spserver/sphttpmsg.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __sphttpmsg_hpp__ 7 | #define __sphttpmsg_hpp__ 8 | 9 | class SP_ArrayList; 10 | class SP_HttpRequest; 11 | class SP_HttpResponse; 12 | class SP_HttpMessage; 13 | 14 | class SP_HttpMsgParser { 15 | public: 16 | SP_HttpMsgParser(); 17 | ~SP_HttpMsgParser(); 18 | 19 | void setIgnoreContent( int ignoreContent ); 20 | int isIgnoreContent() const; 21 | 22 | int append( const void * buffer, int len ); 23 | 24 | // 0 : incomplete, 1 : complete 25 | int isCompleted() const; 26 | 27 | SP_HttpRequest * getRequest() const; 28 | 29 | SP_HttpResponse * getResponse() const; 30 | 31 | private: 32 | static int parseStartLine( SP_HttpMessage ** message, 33 | const void * buffer, int len ); 34 | static int parseHeader( SP_HttpMessage * message, 35 | const void * buffer, int len ); 36 | static int parseChunked( SP_HttpMessage * message, 37 | const void * buffer, int len, int * status ); 38 | static int parseContent( SP_HttpMessage * message, 39 | const void * buffer, int len, int * status ); 40 | static void postProcess( SP_HttpMessage * message ); 41 | 42 | static int getLine( const void * buffer, int len, char * line, int size ); 43 | 44 | SP_HttpMessage * mMessage; 45 | 46 | enum { eStartLine, eHeader, eContent, eCompleted }; 47 | int mStatus; 48 | 49 | int mIgnoreContent; 50 | }; 51 | 52 | class SP_HttpMessage { 53 | public: 54 | static const char * HEADER_CONTENT_LENGTH; 55 | static const char * HEADER_CONTENT_TYPE; 56 | static const char * HEADER_CONNECTION; 57 | static const char * HEADER_PROXY_CONNECTION; 58 | static const char * HEADER_TRANSFER_ENCODING; 59 | static const char * HEADER_DATE; 60 | static const char * HEADER_SERVER; 61 | 62 | public: 63 | SP_HttpMessage( int type ); 64 | virtual ~SP_HttpMessage(); 65 | 66 | enum { eRequest, eResponse }; 67 | int getType() const; 68 | 69 | void setVersion( const char * version ); 70 | const char * getVersion() const; 71 | 72 | void appendContent( const void * content, int length = 0, int maxLength = 0 ); 73 | void setContent( const void * content, int length = 0 ); 74 | void directSetContent( void * content, int length = 0 ); 75 | const void * getContent() const; 76 | int getContentLength() const; 77 | 78 | void addHeader( const char * name, const char * value ); 79 | int removeHeader( const char * name ); 80 | int removeHeader( int index ); 81 | int getHeaderCount() const; 82 | const char * getHeaderName( int index ) const; 83 | const char * getHeaderValue( int index ) const; 84 | const char * getHeaderValue( const char * name ) const; 85 | 86 | int isKeepAlive() const; 87 | 88 | protected: 89 | const int mType; 90 | 91 | char mVersion[ 16 ]; 92 | void * mContent; 93 | int mMaxLength, mContentLength; 94 | 95 | SP_ArrayList * mHeaderNameList, * mHeaderValueList; 96 | }; 97 | 98 | class SP_HttpRequest : public SP_HttpMessage { 99 | public: 100 | SP_HttpRequest(); 101 | virtual ~SP_HttpRequest(); 102 | 103 | void setMethod( const char * method ); 104 | const char * getMethod() const; 105 | 106 | void setURI( const char * uri ); 107 | const char * getURI() const; 108 | 109 | void setURL( const char * url ); 110 | const char * getURL() const; 111 | 112 | void setClinetIP( const char * clientIP ); 113 | const char * getClientIP() const; 114 | 115 | void addParam( const char * name, const char * value ); 116 | int removeParam( const char * name ); 117 | int getParamCount() const; 118 | const char * getParamName( int index ) const; 119 | const char * getParamValue( int index ) const; 120 | const char * getParamValue( const char * name ) const; 121 | 122 | private: 123 | char mMethod[ 16 ], mClientIP[ 16 ]; 124 | char * mURI, * mURL; 125 | 126 | SP_ArrayList * mParamNameList, * mParamValueList; 127 | }; 128 | 129 | class SP_HttpResponse : public SP_HttpMessage { 130 | public: 131 | SP_HttpResponse(); 132 | virtual ~SP_HttpResponse(); 133 | 134 | void setStatusCode( int statusCode ); 135 | int getStatusCode() const; 136 | 137 | void setReasonPhrase( const char * reasonPhrase ); 138 | const char * getReasonPhrase() const; 139 | 140 | private: 141 | int mStatusCode; 142 | char mReasonPhrase[ 128 ]; 143 | }; 144 | 145 | #endif 146 | 147 | -------------------------------------------------------------------------------- /spserver/spiochannel.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spiochannel_hpp__ 7 | #define __spiochannel_hpp__ 8 | 9 | class SP_Session; 10 | class SP_Buffer; 11 | 12 | #ifdef WIN32 13 | typedef struct spwin32buffer sp_evbuffer_t; 14 | #else 15 | typedef struct evbuffer sp_evbuffer_t; 16 | #endif 17 | 18 | struct iovec; 19 | 20 | class SP_IOChannel { 21 | public: 22 | virtual ~SP_IOChannel(); 23 | 24 | // call by an independence thread, can block 25 | // return -1 : terminate session, 0 : continue 26 | virtual int init( int fd ) = 0; 27 | 28 | // run in event-loop thread, cannot block 29 | // return the number of bytes received, or -1 if an error occurred. 30 | virtual int receive( SP_Session * session ) = 0; 31 | 32 | // run in event-loop thread, cannot block 33 | // return the number of bytes sent, or -1 if an error occurred. 34 | virtual int transmit( SP_Session * session ); 35 | 36 | protected: 37 | static sp_evbuffer_t * getEvBuffer( SP_Buffer * buffer ); 38 | 39 | // returns the number of bytes written, or -1 if an error occurred. 40 | virtual int write_vec( struct iovec * iovArray, int iovSize ) = 0; 41 | }; 42 | 43 | class SP_IOChannelFactory { 44 | public: 45 | virtual ~SP_IOChannelFactory(); 46 | 47 | virtual SP_IOChannel * create() const = 0; 48 | }; 49 | 50 | class SP_DefaultIOChannelFactory : public SP_IOChannelFactory { 51 | public: 52 | SP_DefaultIOChannelFactory(); 53 | virtual ~SP_DefaultIOChannelFactory(); 54 | 55 | virtual SP_IOChannel * create() const; 56 | }; 57 | 58 | class SP_DefaultIOChannel : public SP_IOChannel { 59 | public: 60 | SP_DefaultIOChannel(); 61 | ~SP_DefaultIOChannel(); 62 | 63 | virtual int init( int fd ); 64 | virtual int receive( SP_Session * session ); 65 | 66 | protected: 67 | virtual int write_vec( struct iovec * iovArray, int iovSize ); 68 | int mFd; 69 | }; 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /spserver/spiocpdispatcher.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spiocpdispatcher_hpp__ 7 | #define __spiocpdispatcher_hpp__ 8 | 9 | #include "spporting.hpp" 10 | #include "spthread.hpp" 11 | 12 | class SP_CompletionHandler; 13 | class SP_Handler; 14 | class SP_Message; 15 | class SP_BlockingQueue; 16 | class SP_TimerHandler; 17 | class SP_IOChannel; 18 | class SP_Response; 19 | 20 | class SP_IocpEventArg; 21 | class SP_IocpMsgQueue; 22 | 23 | class SP_IocpDispatcher { 24 | public: 25 | SP_IocpDispatcher( SP_CompletionHandler * completionHandler, int maxThreads = 64 ); 26 | ~SP_IocpDispatcher(); 27 | 28 | void setTimeout( int timeout ); 29 | 30 | int getSessionCount(); 31 | int getReqQueueLength(); 32 | 33 | void shutdown(); 34 | int isRunning(); 35 | 36 | /** 37 | * @brief create a thread to run event loop 38 | * @return 0 : OK, -1 : Fail, cannot create thread 39 | */ 40 | int dispatch(); 41 | 42 | /** 43 | * @brief register a fd into dispatcher 44 | * @param needStart : 1 - call handler::start, 0 - don't call handler::start 45 | * @return 0 : OK, -1 : Fail, invalid fd 46 | * @note handler will be deleted by dispatcher when the session is close 47 | */ 48 | int push( int fd, SP_Handler * handler, int needStart = 1 ); 49 | 50 | int push( int fd, SP_Handler * handler, SP_IOChannel * ioChannel, int needStart = 1 ); 51 | 52 | /** 53 | * @brief register a timer into dispatcher 54 | * @param timeout : the interval for the timer 55 | * @note handler will be deleted by dispatcher when the timer is terminated 56 | */ 57 | int push( const struct timeval * timeout, SP_TimerHandler * handler ); 58 | 59 | /** 60 | * @brief push a response 61 | */ 62 | int push( SP_Response * response ); 63 | 64 | private: 65 | int mIsShutdown; 66 | int mIsRunning; 67 | int mMaxThreads; 68 | 69 | SP_IocpEventArg * mEventArg; 70 | SP_CompletionHandler * mCompletionHandler; 71 | 72 | SP_IocpMsgQueue * mPushQueue; 73 | 74 | int start(); 75 | 76 | static sp_thread_result_t SP_THREAD_CALL eventLoop( void * arg ); 77 | 78 | static void onPush( void * queueData, void * arg ); 79 | 80 | static void outputCompleted( void * arg ); 81 | 82 | static void onTimer( void * arg ); 83 | static void timer( void * arg ); 84 | }; 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /spserver/spiocpevent.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spiocpevent_hpp__ 7 | #define __spiocpevent_hpp__ 8 | 9 | #include "spporting.hpp" 10 | 11 | typedef struct tagSP_IocpEvent { 12 | enum { SP_IOCP_MAX_IOV = 8 }; 13 | enum { eEventUnknown, eEventRecv, eEventSend, eEventTimer }; 14 | 15 | OVERLAPPED mOverlapped; 16 | int mType; 17 | WSABUF mWsaBuf; 18 | 19 | void ( * mOnTimer ) ( void * ); 20 | 21 | int mHeapIndex; 22 | struct timeval mTimeout; 23 | } SP_IocpEvent_t; 24 | 25 | class SP_IocpEventHeap { 26 | public: 27 | SP_IocpEventHeap(); 28 | ~SP_IocpEventHeap(); 29 | 30 | int push( SP_IocpEvent_t * item ); 31 | 32 | SP_IocpEvent_t * top(); 33 | 34 | SP_IocpEvent_t * pop(); 35 | 36 | int erase( SP_IocpEvent_t * item ); 37 | 38 | int getCount(); 39 | 40 | private: 41 | 42 | static int isGreater( SP_IocpEvent_t * item1, SP_IocpEvent_t * item2 ); 43 | 44 | int reserve( int count ); 45 | 46 | void shiftUp( int index, SP_IocpEvent_t * item ); 47 | void shiftDown( int index, SP_IocpEvent_t * item ); 48 | 49 | SP_IocpEvent_t ** mEntries; 50 | int mMaxCount, mCount; 51 | }; 52 | 53 | class SP_CircleQueue; 54 | class SP_BlockingQueue; 55 | class SP_SessionManager; 56 | 57 | class SP_IocpMsgQueue { 58 | public: 59 | typedef void ( * QueueFunc_t ) ( void * queueData, void * arg ); 60 | 61 | SP_IocpMsgQueue( HANDLE completionPort, DWORD completionKey, QueueFunc_t func, void * arg ); 62 | ~SP_IocpMsgQueue(); 63 | 64 | int push( void * queueData ); 65 | 66 | int process(); 67 | 68 | private: 69 | HANDLE mCompletionPort; 70 | DWORD mCompletionKey; 71 | QueueFunc_t mFunc; 72 | void * mArg; 73 | 74 | HANDLE mMutex; 75 | SP_CircleQueue * mQueue; 76 | }; 77 | 78 | class SP_IocpEventArg { 79 | public: 80 | SP_IocpEventArg( int timeout ); 81 | ~SP_IocpEventArg(); 82 | 83 | HANDLE getCompletionPort(); 84 | SP_BlockingQueue * getInputResultQueue(); 85 | SP_BlockingQueue * getOutputResultQueue(); 86 | 87 | void setResponseQueue( SP_IocpMsgQueue * responseQueue ); 88 | SP_IocpMsgQueue * getResponseQueue(); 89 | 90 | SP_SessionManager * getSessionManager(); 91 | 92 | SP_IocpEventHeap * getEventHeap(); 93 | 94 | int loadDisconnectEx( SOCKET fd ); 95 | 96 | BOOL disconnectEx( SOCKET fd, LPOVERLAPPED lpOverlapped, 97 | DWORD dwFlags, DWORD reserved ); 98 | 99 | void setTimeout( int timeout ); 100 | int getTimeout(); 101 | 102 | private: 103 | SP_BlockingQueue * mInputResultQueue; 104 | SP_BlockingQueue * mOutputResultQueue; 105 | SP_IocpMsgQueue * mResponseQueue; 106 | 107 | SP_SessionManager * mSessionManager; 108 | 109 | SP_IocpEventHeap * mEventHeap; 110 | 111 | void * mDisconnectExFunc; 112 | 113 | int mTimeout; 114 | 115 | HANDLE mCompletionPort; 116 | }; 117 | 118 | #endif 119 | 120 | -------------------------------------------------------------------------------- /spserver/spiocplfserver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __splfserver_hpp__ 7 | #define __splfserver_hpp__ 8 | 9 | #include "spthread.hpp" 10 | 11 | class SP_IocpEventArg; 12 | class SP_ThreadPool; 13 | class SP_HandlerFactory; 14 | class SP_CompletionHandler; 15 | class SP_IOChannelFactory; 16 | 17 | typedef struct tagSP_IocpAcceptArg SP_IocpAcceptArg_t; 18 | 19 | // leader/follower thread pool server 20 | class SP_IocpLFServer { 21 | public: 22 | SP_IocpLFServer( const char * bindIP, int port, SP_HandlerFactory * handlerFactory ); 23 | ~SP_IocpLFServer(); 24 | 25 | void setTimeout( int timeout ); 26 | void setMaxConnections( int maxConnections ); 27 | void setMaxThreads( int maxThreads ); 28 | void setReqQueueSize( int reqQueueSize, const char * refusedMsg ); 29 | void setIOChannelFactory( SP_IOChannelFactory * ioChannelFactory ); 30 | 31 | void shutdown(); 32 | int isRunning(); 33 | 34 | // return -1 : cannot listen on ip:port, 0 : ok 35 | int run(); 36 | 37 | void runForever(); 38 | 39 | private: 40 | HANDLE mCompletionPort; 41 | char mBindIP[ 64 ]; 42 | int mPort; 43 | int mIsShutdown; 44 | int mIsRunning; 45 | 46 | SP_IocpAcceptArg_t * mAcceptArg; 47 | 48 | SP_IocpEventArg * mEventArg; 49 | 50 | int mMaxThreads; 51 | SP_ThreadPool * mThreadPool; 52 | 53 | SP_CompletionHandler * mCompletionHandler; 54 | 55 | sp_thread_mutex_t mMutex; 56 | 57 | void handleOneEvent(); 58 | 59 | static void lfHandler( void * arg ); 60 | 61 | static void sigHandler( int, short, void * arg ); 62 | 63 | static sp_thread_result_t SP_THREAD_CALL acceptThread( void * arg ); 64 | }; 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /spserver/spiocpserver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spiocpserver_hpp__ 7 | #define __spiocpserver_hpp__ 8 | 9 | #include "spthread.hpp" 10 | 11 | class SP_HandlerFactory; 12 | class SP_IOChannelFactory; 13 | class SP_Session; 14 | class SP_Executor; 15 | 16 | class SP_IocpServer { 17 | public: 18 | SP_IocpServer( const char * bindIP, int port, SP_HandlerFactory * handlerFactory ); 19 | ~SP_IocpServer(); 20 | 21 | void setTimeout( int timeout ); 22 | void setMaxConnections( int maxConnections ); 23 | void setMaxThreads( int maxThreads ); 24 | void setReqQueueSize( int reqQueueSize, const char * refusedMsg ); 25 | void setIOChannelFactory( SP_IOChannelFactory * ioChannelFactory ); 26 | 27 | void shutdown(); 28 | int isRunning(); 29 | int run(); 30 | void runForever(); 31 | 32 | private: 33 | SP_HandlerFactory * mHandlerFactory; 34 | SP_IOChannelFactory * mIOChannelFactory; 35 | 36 | HANDLE mCompletionPort; 37 | char mBindIP[ 64 ]; 38 | int mPort; 39 | int mIsShutdown; 40 | int mIsRunning; 41 | 42 | int mTimeout; 43 | int mMaxThreads; 44 | int mMaxConnections; 45 | int mReqQueueSize; 46 | char * mRefusedMsg; 47 | 48 | static sp_thread_result_t SP_THREAD_CALL acceptThread( void * arg ); 49 | 50 | static sp_thread_result_t SP_THREAD_CALL eventLoop( void * arg ); 51 | 52 | int start(); 53 | 54 | static void sigHandler( int, short, void * arg ); 55 | 56 | static void outputCompleted( void * arg ); 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /spserver/spioutils.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spioutils_hpp__ 7 | #define __spioutils_hpp__ 8 | 9 | #include "spporting.hpp" 10 | 11 | class SP_IOUtils { 12 | public: 13 | static void inetNtoa( in_addr * addr, char * ip, int size ); 14 | 15 | static int setNonblock( int fd ); 16 | 17 | static int setBlock( int fd ); 18 | 19 | static int tcpListen( const char * ip, int port, int * fd, int blocking = 1 ); 20 | 21 | static int initDaemon( const char * workdir = 0 ); 22 | 23 | static int tcpListen( const char * path, int * fd, int blocking = 1, int mode = 0666 ); 24 | 25 | private: 26 | SP_IOUtils(); 27 | }; 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /spserver/splfserver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __splfserver_hpp__ 7 | #define __splfserver_hpp__ 8 | 9 | #include "spthread.hpp" 10 | 11 | class SP_EventArg; 12 | class SP_ThreadPool; 13 | class SP_HandlerFactory; 14 | class SP_CompletionHandler; 15 | class SP_IOChannelFactory; 16 | 17 | typedef struct tagSP_AcceptArg SP_AcceptArg_t; 18 | 19 | struct event; 20 | 21 | // leader/follower thread pool server 22 | class SP_LFServer { 23 | public: 24 | SP_LFServer( const char * bindIP, int port, SP_HandlerFactory * handlerFactory ); 25 | ~SP_LFServer(); 26 | 27 | void setTimeout( int timeout ); 28 | void setMaxConnections( int maxConnections ); 29 | void setMaxThreads( int maxThreads ); 30 | void setReqQueueSize( int reqQueueSize, const char * refusedMsg ); 31 | void setIOChannelFactory( SP_IOChannelFactory * ioChannelFactory ); 32 | 33 | void shutdown(); 34 | int isRunning(); 35 | 36 | // return -1 : cannot listen on ip:port, 0 : ok 37 | int run(); 38 | 39 | void runForever(); 40 | 41 | private: 42 | char mBindIP[ 64 ]; 43 | int mPort; 44 | int mIsShutdown; 45 | int mIsRunning; 46 | 47 | SP_AcceptArg_t * mAcceptArg; 48 | 49 | SP_EventArg * mEventArg; 50 | 51 | int mMaxThreads; 52 | SP_ThreadPool * mThreadPool; 53 | 54 | SP_CompletionHandler * mCompletionHandler; 55 | 56 | struct event * mEvAccept; 57 | struct event * mEvSigInt, * mEvSigTerm; 58 | 59 | sp_thread_mutex_t mMutex; 60 | 61 | void handleOneEvent(); 62 | 63 | static void lfHandler( void * arg ); 64 | 65 | static void sigHandler( int, short, void * arg ); 66 | }; 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /spserver/spmsgblock.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include "spmsgblock.hpp" 7 | 8 | #include "spbuffer.hpp" 9 | #include "sputils.hpp" 10 | 11 | SP_MsgBlock :: ~SP_MsgBlock() 12 | { 13 | } 14 | 15 | //--------------------------------------------------------- 16 | 17 | SP_MsgBlockList :: SP_MsgBlockList() 18 | { 19 | mList = new SP_ArrayList(); 20 | } 21 | 22 | SP_MsgBlockList :: ~SP_MsgBlockList() 23 | { 24 | for( int i = 0; i < mList->getCount(); i++ ) { 25 | SP_MsgBlock * msgBlock = (SP_MsgBlock*)mList->getItem( i ); 26 | delete msgBlock; 27 | } 28 | delete mList; 29 | 30 | mList = NULL; 31 | } 32 | 33 | void SP_MsgBlockList :: reset() 34 | { 35 | for( ; mList->getCount() > 0; ) { 36 | SP_MsgBlock * msgBlock = (SP_MsgBlock*)mList->takeItem( SP_ArrayList::LAST_INDEX ); 37 | delete msgBlock; 38 | } 39 | } 40 | 41 | size_t SP_MsgBlockList :: getTotalSize() const 42 | { 43 | size_t totalSize = 0; 44 | 45 | for( int i = 0; i < mList->getCount(); i++ ) { 46 | SP_MsgBlock * msgBlock = (SP_MsgBlock*)mList->getItem( i ); 47 | totalSize += msgBlock->getSize(); 48 | } 49 | 50 | return totalSize; 51 | } 52 | 53 | int SP_MsgBlockList :: getCount() const 54 | { 55 | return mList->getCount(); 56 | } 57 | 58 | int SP_MsgBlockList :: append( SP_MsgBlock * msgBlock ) 59 | { 60 | return mList->append( msgBlock ); 61 | } 62 | 63 | const SP_MsgBlock * SP_MsgBlockList :: getItem( int index ) const 64 | { 65 | return (SP_MsgBlock*)mList->getItem( index ); 66 | } 67 | 68 | SP_MsgBlock * SP_MsgBlockList :: takeItem( int index ) 69 | { 70 | return (SP_MsgBlock*)mList->takeItem( index ); 71 | } 72 | 73 | //--------------------------------------------------------- 74 | 75 | SP_BufferMsgBlock :: SP_BufferMsgBlock() 76 | { 77 | mBuffer = new SP_Buffer(); 78 | mToBeOwner = 1; 79 | } 80 | 81 | SP_BufferMsgBlock :: SP_BufferMsgBlock( SP_Buffer * buffer, int toBeOwner ) 82 | { 83 | mBuffer = buffer; 84 | mToBeOwner = toBeOwner; 85 | } 86 | 87 | SP_BufferMsgBlock :: ~SP_BufferMsgBlock() 88 | { 89 | if( mToBeOwner ) delete mBuffer; 90 | mBuffer = NULL; 91 | } 92 | 93 | const void * SP_BufferMsgBlock :: getData() const 94 | { 95 | return mBuffer->getBuffer(); 96 | } 97 | 98 | size_t SP_BufferMsgBlock :: getSize() const 99 | { 100 | return mBuffer->getSize(); 101 | } 102 | 103 | int SP_BufferMsgBlock :: append( const void * buffer, size_t len ) 104 | { 105 | return mBuffer->append( buffer, len ); 106 | } 107 | 108 | //--------------------------------------------------------- 109 | 110 | SP_SimpleMsgBlock :: SP_SimpleMsgBlock() 111 | { 112 | mData = NULL; 113 | mSize = 0; 114 | mToBeOwner = 0; 115 | } 116 | 117 | SP_SimpleMsgBlock :: SP_SimpleMsgBlock( void * data, size_t size, int toBeOwner ) 118 | { 119 | mData = data; 120 | mSize = size; 121 | mToBeOwner = toBeOwner; 122 | } 123 | 124 | SP_SimpleMsgBlock :: ~SP_SimpleMsgBlock() 125 | { 126 | if( mToBeOwner && NULL != mData ) { 127 | free( mData ); 128 | mData = NULL; 129 | } 130 | } 131 | 132 | const void * SP_SimpleMsgBlock :: getData() const 133 | { 134 | return mData; 135 | } 136 | 137 | size_t SP_SimpleMsgBlock :: getSize() const 138 | { 139 | return mSize; 140 | } 141 | 142 | void SP_SimpleMsgBlock :: setData( void * data, size_t size, int toBeOwner ) 143 | { 144 | if( mToBeOwner && NULL != mData ) { 145 | free( mData ); 146 | } 147 | 148 | mData = data; 149 | mSize = size; 150 | mToBeOwner = toBeOwner; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /spserver/spmsgblock.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spmsgblock_hpp__ 7 | #define __spmsgblock_hpp__ 8 | 9 | #include 10 | 11 | class SP_Buffer; 12 | class SP_ArrayList; 13 | 14 | class SP_MsgBlock { 15 | public: 16 | virtual ~SP_MsgBlock(); 17 | 18 | virtual const void * getData() const = 0; 19 | virtual size_t getSize() const = 0; 20 | }; 21 | 22 | class SP_MsgBlockList { 23 | public: 24 | SP_MsgBlockList(); 25 | ~SP_MsgBlockList(); 26 | 27 | void reset(); 28 | 29 | size_t getTotalSize() const; 30 | 31 | int getCount() const; 32 | int append( SP_MsgBlock * msgBlock ); 33 | const SP_MsgBlock * getItem( int index ) const; 34 | SP_MsgBlock * takeItem( int index ); 35 | 36 | private: 37 | SP_MsgBlockList( SP_MsgBlockList & ); 38 | SP_MsgBlockList & operator=( SP_MsgBlockList & ); 39 | 40 | SP_ArrayList * mList; 41 | }; 42 | 43 | class SP_BufferMsgBlock : public SP_MsgBlock { 44 | public: 45 | SP_BufferMsgBlock(); 46 | SP_BufferMsgBlock( SP_Buffer * buffer, int toBeOwner ); 47 | virtual ~SP_BufferMsgBlock(); 48 | 49 | virtual const void * getData() const; 50 | virtual size_t getSize() const; 51 | 52 | int append( const void * buffer, size_t len = 0 ); 53 | 54 | private: 55 | SP_BufferMsgBlock( SP_BufferMsgBlock & ); 56 | SP_BufferMsgBlock & operator=( SP_BufferMsgBlock & ); 57 | 58 | SP_Buffer * mBuffer; 59 | int mToBeOwner; 60 | }; 61 | 62 | class SP_SimpleMsgBlock : public SP_MsgBlock { 63 | public: 64 | SP_SimpleMsgBlock(); 65 | SP_SimpleMsgBlock( void * data, size_t size, int toBeOwner ); 66 | virtual ~SP_SimpleMsgBlock(); 67 | 68 | virtual const void * getData() const; 69 | virtual size_t getSize() const; 70 | 71 | void setData( void * data, size_t size, int toBeOwner ); 72 | 73 | private: 74 | SP_SimpleMsgBlock( SP_SimpleMsgBlock & ); 75 | SP_SimpleMsgBlock & operator=( SP_SimpleMsgBlock & ); 76 | 77 | void * mData; 78 | size_t mSize; 79 | int mToBeOwner; 80 | }; 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /spserver/spmsgdecoder.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spmsgdecoder_hpp__ 7 | #define __spmsgdecoder_hpp__ 8 | 9 | class SP_Buffer; 10 | 11 | class SP_MsgDecoder { 12 | public: 13 | virtual ~SP_MsgDecoder(); 14 | 15 | enum { eOK, eMoreData }; 16 | 17 | virtual int decode( SP_Buffer * inBuffer ) = 0; 18 | }; 19 | 20 | class SP_DefaultMsgDecoder : public SP_MsgDecoder { 21 | public: 22 | SP_DefaultMsgDecoder(); 23 | virtual ~SP_DefaultMsgDecoder(); 24 | 25 | // always return SP_MsgDecoder::eOK, move buffer from inBuffer to mBuffer 26 | virtual int decode( SP_Buffer * inBuffer ); 27 | 28 | SP_Buffer * getMsg(); 29 | 30 | private: 31 | SP_Buffer * mBuffer; 32 | }; 33 | 34 | class SP_LineMsgDecoder : public SP_MsgDecoder { 35 | public: 36 | SP_LineMsgDecoder(); 37 | virtual ~SP_LineMsgDecoder(); 38 | 39 | // return SP_MsgDecoder::eMoreData until meet 40 | virtual int decode( SP_Buffer * inBuffer ); 41 | 42 | const char * getMsg(); 43 | 44 | private: 45 | char * mLine; 46 | }; 47 | 48 | class SP_CircleQueue; 49 | 50 | class SP_MultiLineMsgDecoder : public SP_MsgDecoder { 51 | public: 52 | SP_MultiLineMsgDecoder(); 53 | ~SP_MultiLineMsgDecoder(); 54 | 55 | // return SP_MsgDecoder::eMoreData until meet 56 | virtual int decode( SP_Buffer * inBuffer ); 57 | 58 | SP_CircleQueue * getQueue(); 59 | 60 | private: 61 | SP_CircleQueue * mQueue; 62 | }; 63 | 64 | class SP_DotTermMsgDecoder : public SP_MsgDecoder { 65 | public: 66 | SP_DotTermMsgDecoder(); 67 | virtual ~SP_DotTermMsgDecoder(); 68 | 69 | // return SP_MsgDecoder::eMoreData until meet . 70 | virtual int decode( SP_Buffer * inBuffer ); 71 | 72 | const char * getMsg(); 73 | 74 | private: 75 | char * mBuffer; 76 | }; 77 | 78 | class SP_ArrayList; 79 | 80 | class SP_DotTermChunkMsgDecoder : public SP_MsgDecoder { 81 | public: 82 | 83 | enum { MAX_SIZE_PER_CHUNK = 1024 * 64 }; 84 | 85 | public: 86 | SP_DotTermChunkMsgDecoder(); 87 | virtual ~SP_DotTermChunkMsgDecoder(); 88 | 89 | // return SP_MsgDecoder::eMoreData until meet . 90 | virtual int decode( SP_Buffer * inBuffer ); 91 | 92 | // caller need to free return value 93 | char * getMsg(); 94 | 95 | private: 96 | SP_ArrayList * mList; 97 | }; 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /spserver/spporting.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spporting_hpp__ 7 | #define __spporting_hpp__ 8 | 9 | #ifdef WIN32 10 | 11 | #include "spwin32port.hpp" 12 | 13 | #else 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define sp_syslog syslog 30 | #define sp_openlog openlog 31 | #define sp_closelog closelog 32 | 33 | #define sp_inet_aton inet_aton 34 | #define sp_close close 35 | #define sp_writev writev 36 | #define sp_socketpair socketpair 37 | #define sp_gettimeofday gettimeofday 38 | 39 | inline int sp_initsock() 40 | { 41 | return 0; 42 | } 43 | 44 | #ifndef LOG_PERROR 45 | #define LOG_PERROR 0 46 | #endif 47 | 48 | #endif 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /spserver/sprequest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include "spporting.hpp" 10 | 11 | #include "sprequest.hpp" 12 | #include "spmsgdecoder.hpp" 13 | #include "sputils.hpp" 14 | 15 | SP_Request :: SP_Request() 16 | { 17 | mDecoder = new SP_DefaultMsgDecoder(); 18 | 19 | memset( mClientIP, 0, sizeof( mClientIP ) ); 20 | mClientPort = 0; 21 | 22 | memset( mServerIP, 0, sizeof( mServerIP ) ); 23 | } 24 | 25 | SP_Request :: ~SP_Request() 26 | { 27 | if( NULL != mDecoder ) delete mDecoder; 28 | mDecoder = NULL; 29 | } 30 | 31 | SP_MsgDecoder * SP_Request :: getMsgDecoder() 32 | { 33 | return mDecoder; 34 | } 35 | 36 | void SP_Request :: setMsgDecoder( SP_MsgDecoder * decoder ) 37 | { 38 | if( NULL != mDecoder ) delete mDecoder; 39 | mDecoder = decoder; 40 | } 41 | 42 | void SP_Request :: setClientIP( const char * clientIP ) 43 | { 44 | sp_strlcpy( mClientIP, clientIP, sizeof( mClientIP ) ); 45 | } 46 | 47 | const char * SP_Request :: getClientIP() 48 | { 49 | return mClientIP; 50 | } 51 | 52 | void SP_Request :: setClientPort( int port ) 53 | { 54 | mClientPort = port; 55 | } 56 | 57 | int SP_Request :: getClientPort() 58 | { 59 | return mClientPort; 60 | } 61 | 62 | void SP_Request :: setServerIP( const char * ip ) 63 | { 64 | sp_strlcpy( mServerIP, ip, sizeof( mServerIP ) ); 65 | } 66 | 67 | const char * SP_Request :: getServerIP() 68 | { 69 | return mServerIP; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /spserver/sprequest.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __sprequest_hpp__ 7 | #define __sprequest_hpp__ 8 | 9 | #include "spporting.hpp" 10 | 11 | class SP_MsgDecoder; 12 | 13 | class SP_Request { 14 | public: 15 | SP_Request(); 16 | ~SP_Request(); 17 | 18 | // default return SP_DefaultMsgDecoder 19 | SP_MsgDecoder * getMsgDecoder(); 20 | 21 | // set a special SP_MsgDecoder 22 | void setMsgDecoder( SP_MsgDecoder * decoder ); 23 | 24 | void setClientIP( const char * clientIP ); 25 | const char * getClientIP(); 26 | 27 | void setClientPort( int port ); 28 | int getClientPort(); 29 | 30 | void setServerIP( const char * ip ); 31 | const char * getServerIP(); 32 | 33 | private: 34 | SP_MsgDecoder * mDecoder; 35 | 36 | char mClientIP[ 32 ]; 37 | int mClientPort; 38 | 39 | char mServerIP[ 32 ]; 40 | }; 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /spserver/spresponse.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spresponse_hpp__ 8 | #define __spresponse_hpp__ 9 | 10 | #include 11 | #include "spporting.hpp" 12 | 13 | class SP_Buffer; 14 | struct evbuffer; 15 | class SP_ArrayList; 16 | class SP_MsgBlockList; 17 | 18 | typedef struct tagSP_Sid { 19 | uint16_t mKey; 20 | uint16_t mSeq; 21 | 22 | enum { 23 | eTimerKey = 0, 24 | eTimerSeq = 65535, 25 | 26 | ePushKey = 1, 27 | ePushSeq = 65535 28 | }; 29 | } SP_Sid_t; 30 | 31 | class SP_SidList { 32 | public: 33 | SP_SidList(); 34 | ~SP_SidList(); 35 | 36 | void reset(); 37 | 38 | int getCount() const; 39 | void add( SP_Sid_t sid ); 40 | SP_Sid_t get( int index ) const; 41 | SP_Sid_t take( int index ); 42 | 43 | int find( SP_Sid_t sid ) const; 44 | 45 | private: 46 | SP_SidList( SP_SidList & ); 47 | SP_SidList & operator=( SP_SidList & ); 48 | 49 | SP_ArrayList * mList; 50 | }; 51 | 52 | class SP_Message { 53 | public: 54 | SP_Message( int completionKey = 0 ); 55 | ~SP_Message(); 56 | 57 | void reset(); 58 | 59 | SP_SidList * getToList(); 60 | 61 | size_t getTotalSize(); 62 | 63 | SP_Buffer * getMsg(); 64 | SP_MsgBlockList * getFollowBlockList(); 65 | 66 | SP_SidList * getSuccess(); 67 | SP_SidList * getFailure(); 68 | 69 | void setCompletionKey( int completionKey ); 70 | int getCompletionKey(); 71 | 72 | private: 73 | SP_Message( SP_Message & ); 74 | SP_Message & operator=( SP_Message & ); 75 | 76 | SP_Buffer * mMsg; 77 | SP_MsgBlockList * mFollowBlockList; 78 | 79 | SP_SidList * mToList; 80 | SP_SidList * mSuccess; 81 | SP_SidList * mFailure; 82 | 83 | int mCompletionKey; 84 | }; 85 | 86 | class SP_Response { 87 | public: 88 | SP_Response( SP_Sid_t fromSid ); 89 | ~SP_Response(); 90 | 91 | SP_Sid_t getFromSid() const; 92 | SP_Message * getReply(); 93 | 94 | void addMessage( SP_Message * msg ); 95 | SP_Message * peekMessage(); 96 | SP_Message * takeMessage(); 97 | 98 | SP_SidList * getToCloseList(); 99 | 100 | private: 101 | SP_Response( SP_Response & ); 102 | SP_Response & operator=( SP_Response & ); 103 | 104 | SP_Sid_t mFromSid; 105 | SP_Message * mReply; 106 | SP_SidList * mToCloseList; 107 | 108 | SP_ArrayList * mList; 109 | }; 110 | 111 | #endif 112 | 113 | -------------------------------------------------------------------------------- /spserver/spserver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spserver_hpp__ 8 | #define __spserver_hpp__ 9 | 10 | #include 11 | #include "spthread.hpp" 12 | 13 | class SP_HandlerFactory; 14 | class SP_Session; 15 | class SP_Executor; 16 | class SP_IOChannelFactory; 17 | 18 | struct event; 19 | 20 | // half-sync/half-async thread pool server 21 | class SP_Server { 22 | public: 23 | SP_Server( const char * bindIP, int port, SP_HandlerFactory * handlerFactory ); 24 | ~SP_Server(); 25 | 26 | void setTimeout( int timeout ); 27 | void setMaxConnections( int maxConnections ); 28 | void setMaxThreads( int maxThreads ); 29 | void setReqQueueSize( int reqQueueSize, const char * refusedMsg ); 30 | void setIOChannelFactory( SP_IOChannelFactory * ioChannelFactory ); 31 | 32 | void shutdown(); 33 | int isRunning(); 34 | int run(); 35 | void runForever(); 36 | 37 | private: 38 | SP_HandlerFactory * mHandlerFactory; 39 | SP_IOChannelFactory * mIOChannelFactory; 40 | 41 | char mBindIP[ 64 ]; 42 | int mPort; 43 | int mIsShutdown; 44 | int mIsRunning; 45 | 46 | int mTimeout; 47 | int mMaxThreads; 48 | int mMaxConnections; 49 | int mReqQueueSize; 50 | char * mRefusedMsg; 51 | 52 | static sp_thread_result_t SP_THREAD_CALL eventLoop( void * arg ); 53 | 54 | int start(); 55 | 56 | static void sigHandler( int, short, void * arg ); 57 | 58 | static void outputCompleted( void * arg ); 59 | }; 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /spserver/spsession.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spsession_hpp__ 8 | #define __spsession_hpp__ 9 | 10 | #include "spresponse.hpp" 11 | 12 | class SP_Handler; 13 | class SP_Buffer; 14 | class SP_Session; 15 | class SP_ArrayList; 16 | class SP_Request; 17 | class SP_IOChannel; 18 | 19 | struct event; 20 | 21 | class SP_Session { 22 | public: 23 | SP_Session( SP_Sid_t sid ); 24 | virtual ~SP_Session(); 25 | 26 | struct event * getReadEvent(); 27 | struct event * getWriteEvent(); 28 | 29 | void setHandler( SP_Handler * handler ); 30 | SP_Handler * getHandler(); 31 | 32 | void setArg( void * arg ); 33 | void * getArg(); 34 | 35 | SP_Sid_t getSid(); 36 | 37 | SP_Buffer * getInBuffer(); 38 | SP_Request * getRequest(); 39 | 40 | void setOutOffset( int offset ); 41 | int getOutOffset(); 42 | SP_ArrayList * getOutList(); 43 | 44 | enum { eNormal, eWouldExit, eExit }; 45 | void setStatus( int status ); 46 | int getStatus(); 47 | 48 | int getRunning(); 49 | void setRunning( int running ); 50 | 51 | int getReading(); 52 | void setReading( int reading ); 53 | 54 | int getWriting(); 55 | void setWriting( int writing ); 56 | 57 | SP_IOChannel * getIOChannel(); 58 | void setIOChannel( SP_IOChannel * ioChannel ); 59 | 60 | unsigned int getTotalRead(); 61 | void addRead( int len ); 62 | 63 | unsigned int getTotalWrite(); 64 | void addWrite( int len ); 65 | 66 | private: 67 | 68 | SP_Session( SP_Session & ); 69 | SP_Session & operator=( SP_Session & ); 70 | 71 | SP_Sid_t mSid; 72 | 73 | struct event * mReadEvent; 74 | struct event * mWriteEvent; 75 | 76 | SP_Handler * mHandler; 77 | void * mArg; 78 | 79 | SP_Buffer * mInBuffer; 80 | SP_Request * mRequest; 81 | 82 | int mOutOffset; 83 | SP_ArrayList * mOutList; 84 | 85 | char mStatus; 86 | char mRunning; 87 | char mWriting; 88 | char mReading; 89 | 90 | unsigned int mTotalRead, mTotalWrite; 91 | 92 | SP_IOChannel * mIOChannel; 93 | }; 94 | 95 | typedef struct tagSP_SessionEntry SP_SessionEntry_t; 96 | 97 | class SP_SessionManager { 98 | public: 99 | SP_SessionManager(); 100 | ~SP_SessionManager(); 101 | 102 | int getCount(); 103 | void put( uint16_t key, uint16_t seq, SP_Session * session ); 104 | SP_Session * get( uint16_t key, uint16_t * seq ); 105 | SP_Session * remove( uint16_t key, uint16_t seq ); 106 | 107 | int getFreeCount(); 108 | // > 0 : OK, 0 : out of memory 109 | uint16_t allocKey( uint16_t * seq ); 110 | 111 | private: 112 | enum { eColPerRow = 1024 }; 113 | 114 | int mCount; 115 | SP_SessionEntry_t * mArray[ 64 ]; 116 | 117 | int mFreeCount; 118 | uint16_t mFreeList; 119 | }; 120 | 121 | #endif 122 | 123 | -------------------------------------------------------------------------------- /spserver/spsmtp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spsmtp_hpp__ 7 | #define __spsmtp_hpp__ 8 | 9 | #include "sphandler.hpp" 10 | 11 | class SP_Buffer; 12 | class SP_ArrayList; 13 | 14 | class SP_SmtpHandler { 15 | public: 16 | virtual ~SP_SmtpHandler(); 17 | 18 | virtual void error(); 19 | 20 | virtual void timeout(); 21 | 22 | enum { 23 | eAccept = 0, // command accepted 24 | eReject = -1, // command rejected 25 | eClose = -2 // force to close the connection 26 | }; 27 | 28 | virtual int welcome( const char * clientIP, const char * serverIP, SP_Buffer * reply ); 29 | 30 | virtual int help( const char * args, SP_Buffer * reply ); 31 | 32 | virtual int helo( const char * args, SP_Buffer * reply ); 33 | 34 | virtual int ehlo( const char * args, SP_Buffer * reply ); 35 | 36 | /** 37 | * Called after the AUTH LOGIN during a SMTP exchange. 38 | * 39 | * @param user is the encoded username 40 | * @param pass is the encoded password 41 | */ 42 | virtual int auth( const char * user, const char * pass, SP_Buffer * reply ); 43 | 44 | virtual int noop( const char * args, SP_Buffer * reply ); 45 | 46 | /** 47 | * Called first, after the MAIL FROM during a SMTP exchange. 48 | * 49 | * @param args is the args of the MAIL FROM 50 | */ 51 | virtual int from( const char * args, SP_Buffer * reply ) = 0; 52 | 53 | /** 54 | * Called once for every RCPT TO during a SMTP exchange. 55 | * This will occur after a from() call. 56 | * 57 | * @param args is the args of the RCPT TO 58 | */ 59 | virtual int rcpt( const char * args, SP_Buffer * reply ) = 0; 60 | 61 | /** 62 | * Called when the DATA part of the SMTP exchange begins. Will 63 | * only be called if at least one recipient was accepted. 64 | * 65 | * @param data will be the smtp data stream, stripped of any extra '.' chars 66 | */ 67 | virtual int data( const char * data, SP_Buffer * reply ) = 0; 68 | 69 | /** 70 | * This method is called whenever a RSET command is sent. It should 71 | * be used to clean up any pending deliveries. 72 | */ 73 | virtual int rset( SP_Buffer * reply ) = 0; 74 | }; 75 | 76 | class SP_SmtpHandlerList { 77 | public: 78 | SP_SmtpHandlerList(); 79 | ~SP_SmtpHandlerList(); 80 | 81 | int getCount(); 82 | void append( SP_SmtpHandler * handler ); 83 | SP_SmtpHandler * getItem( int index ); 84 | 85 | private: 86 | SP_ArrayList * mList; 87 | }; 88 | 89 | class SP_SmtpHandlerFactory { 90 | public: 91 | virtual ~SP_SmtpHandlerFactory(); 92 | 93 | virtual SP_SmtpHandler * create() const = 0; 94 | }; 95 | 96 | class SP_SmtpHandlerAdapterFactory : public SP_HandlerFactory { 97 | public: 98 | SP_SmtpHandlerAdapterFactory( SP_SmtpHandlerFactory * factory ); 99 | 100 | virtual ~SP_SmtpHandlerAdapterFactory(); 101 | 102 | virtual SP_Handler * create() const; 103 | 104 | private: 105 | SP_SmtpHandlerFactory * mFactory; 106 | }; 107 | 108 | #endif 109 | 110 | -------------------------------------------------------------------------------- /spserver/spthread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "spthread.hpp" 3 | 4 | #ifdef WIN32 5 | 6 | int sp_thread_mutex_init( sp_thread_mutex_t * mutex, void * attr ) 7 | { 8 | *mutex = CreateMutex( NULL, FALSE, NULL ); 9 | return NULL == * mutex ? GetLastError() : 0; 10 | } 11 | 12 | int sp_thread_mutex_destroy( sp_thread_mutex_t * mutex ) 13 | { 14 | int ret = CloseHandle( *mutex ); 15 | 16 | return 0 == ret ? GetLastError() : 0; 17 | } 18 | 19 | int sp_thread_mutex_lock( sp_thread_mutex_t * mutex ) 20 | { 21 | int ret = WaitForSingleObject( *mutex, INFINITE ); 22 | return WAIT_OBJECT_0 == ret ? 0 : GetLastError(); 23 | } 24 | 25 | int sp_thread_mutex_unlock( sp_thread_mutex_t * mutex ) 26 | { 27 | int ret = ReleaseMutex( *mutex ); 28 | return 0 != ret ? 0 : GetLastError(); 29 | } 30 | 31 | int sp_thread_cond_init( sp_thread_cond_t * cond, void * attr ) 32 | { 33 | *cond = CreateEvent( NULL, FALSE, FALSE, NULL ); 34 | return NULL == *cond ? GetLastError() : 0; 35 | } 36 | 37 | int sp_thread_cond_destroy( sp_thread_cond_t * cond ) 38 | { 39 | int ret = CloseHandle( *cond ); 40 | return 0 == ret ? GetLastError() : 0; 41 | } 42 | 43 | /* 44 | Caller MUST be holding the mutex lock; the 45 | lock is released and the caller is blocked waiting 46 | on 'cond'. When 'cond' is signaled, the mutex 47 | is re-acquired before returning to the caller. 48 | */ 49 | int sp_thread_cond_wait( sp_thread_cond_t * cond, sp_thread_mutex_t * mutex ) 50 | { 51 | int ret = 0; 52 | 53 | sp_thread_mutex_unlock( mutex ); 54 | 55 | ret = WaitForSingleObject( *cond, INFINITE ); 56 | 57 | sp_thread_mutex_lock( mutex ); 58 | 59 | return WAIT_OBJECT_0 == ret ? 0 : GetLastError(); 60 | } 61 | 62 | int sp_thread_cond_signal( sp_thread_cond_t * cond ) 63 | { 64 | int ret = SetEvent( *cond ); 65 | return 0 == ret ? GetLastError() : 0; 66 | } 67 | 68 | sp_thread_t sp_thread_self() 69 | { 70 | return GetCurrentThreadId(); 71 | } 72 | 73 | int sp_thread_attr_init( sp_thread_attr_t * attr ) 74 | { 75 | memset( attr, 0, sizeof( sp_thread_attr_t ) ); 76 | return 0; 77 | } 78 | 79 | int sp_thread_attr_destroy( sp_thread_attr_t * attr ) 80 | { 81 | return 0; 82 | } 83 | 84 | int sp_thread_attr_setdetachstate( sp_thread_attr_t * attr, int detachstate ) 85 | { 86 | attr->detachstate = detachstate; 87 | return 0; 88 | } 89 | 90 | int sp_thread_attr_setstacksize( sp_thread_attr_t * attr, size_t stacksize ) 91 | { 92 | attr->stacksize = stacksize; 93 | return 0; 94 | } 95 | 96 | int sp_thread_create( sp_thread_t * thread, sp_thread_attr_t * attr, 97 | sp_thread_func_t myfunc, void * args ) 98 | { 99 | // _beginthreadex returns 0 on an error 100 | HANDLE h = 0; 101 | 102 | if( NULL != attr ) { 103 | h = (HANDLE)_beginthreadex( NULL, attr->stacksize, myfunc, args, 0, thread ); 104 | } else { 105 | h = (HANDLE)_beginthreadex( NULL, 0, myfunc, args, 0, thread ); 106 | } 107 | 108 | return h > 0 ? 0 : GetLastError(); 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /spserver/spthread.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __spthread_hpp__ 3 | #define __spthread_hpp__ 4 | 5 | #ifndef WIN32 6 | 7 | /// pthread 8 | 9 | #include 10 | #include 11 | 12 | typedef void * sp_thread_result_t; 13 | typedef pthread_mutex_t sp_thread_mutex_t; 14 | typedef pthread_cond_t sp_thread_cond_t; 15 | typedef pthread_t sp_thread_t; 16 | typedef pthread_attr_t sp_thread_attr_t; 17 | 18 | #define sp_thread_mutex_init pthread_mutex_init 19 | #define sp_thread_mutex_destroy pthread_mutex_destroy 20 | #define sp_thread_mutex_lock pthread_mutex_lock 21 | #define sp_thread_mutex_unlock pthread_mutex_unlock 22 | 23 | #define sp_thread_cond_init pthread_cond_init 24 | #define sp_thread_cond_destroy pthread_cond_destroy 25 | #define sp_thread_cond_wait pthread_cond_wait 26 | #define sp_thread_cond_signal pthread_cond_signal 27 | 28 | #define sp_thread_attr_init pthread_attr_init 29 | #define sp_thread_attr_destroy pthread_attr_destroy 30 | #define sp_thread_attr_setdetachstate pthread_attr_setdetachstate 31 | #define SP_THREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED 32 | #define sp_thread_attr_setstacksize pthread_attr_setstacksize 33 | 34 | #define sp_thread_self pthread_self 35 | #define sp_thread_create pthread_create 36 | 37 | #define SP_THREAD_CALL 38 | typedef sp_thread_result_t ( * sp_thread_func_t )( void * args ); 39 | 40 | #ifndef sp_sleep 41 | #define sp_sleep(x) sleep(x) 42 | #endif 43 | 44 | #else /////////////////////////////////////////////////////////////////////// 45 | 46 | // win32 thread 47 | 48 | #include 49 | #include 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | typedef unsigned sp_thread_t; 56 | 57 | typedef unsigned sp_thread_result_t; 58 | #define SP_THREAD_CALL __stdcall 59 | typedef sp_thread_result_t ( __stdcall * sp_thread_func_t )( void * args ); 60 | 61 | typedef HANDLE sp_thread_mutex_t; 62 | typedef HANDLE sp_thread_cond_t; 63 | 64 | //typedef DWORD sp_thread_attr_t; 65 | typedef struct tagsp_thread_attr { 66 | int stacksize; 67 | int detachstate; 68 | } sp_thread_attr_t; 69 | 70 | #define SP_THREAD_CREATE_DETACHED 1 71 | 72 | #ifndef sp_sleep 73 | #define sp_sleep(x) Sleep(1000*x) 74 | #endif 75 | 76 | int sp_thread_mutex_init( sp_thread_mutex_t * mutex, void * attr ); 77 | int sp_thread_mutex_destroy( sp_thread_mutex_t * mutex ); 78 | int sp_thread_mutex_lock( sp_thread_mutex_t * mutex ); 79 | int sp_thread_mutex_unlock( sp_thread_mutex_t * mutex ); 80 | 81 | int sp_thread_cond_init( sp_thread_cond_t * cond, void * attr ); 82 | int sp_thread_cond_destroy( sp_thread_cond_t * cond ); 83 | int sp_thread_cond_wait( sp_thread_cond_t * cond, sp_thread_mutex_t * mutex ); 84 | int sp_thread_cond_signal( sp_thread_cond_t * cond ); 85 | 86 | int sp_thread_attr_init( sp_thread_attr_t * attr ); 87 | int sp_thread_attr_destroy( sp_thread_attr_t * attr ); 88 | int sp_thread_attr_setdetachstate( sp_thread_attr_t * attr, int detachstate ); 89 | int sp_thread_attr_setstacksize( sp_thread_attr_t * attr, size_t stacksize ); 90 | 91 | int sp_thread_create( sp_thread_t * thread, sp_thread_attr_t * attr, 92 | sp_thread_func_t myfunc, void * args ); 93 | sp_thread_t sp_thread_self(); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /spserver/spthreadpool.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | 7 | #ifndef __spthreadpool_hpp__ 8 | #define __spthreadpool_hpp__ 9 | 10 | #include "spthread.hpp" 11 | 12 | typedef struct tagSP_Thread SP_Thread_t; 13 | 14 | class SP_ThreadPool { 15 | public: 16 | typedef void ( * DispatchFunc_t )( void * ); 17 | 18 | SP_ThreadPool( int maxThreads, const char * tag = 0 ); 19 | ~SP_ThreadPool(); 20 | 21 | /// @return 0 : OK, -1 : cannot create thread 22 | int dispatch( DispatchFunc_t dispatchFunc, void *arg ); 23 | 24 | int getMaxThreads(); 25 | 26 | private: 27 | char * mTag; 28 | 29 | int mMaxThreads; 30 | int mIndex; 31 | int mTotal; 32 | int mIsShutdown; 33 | 34 | sp_thread_mutex_t mMainMutex; 35 | sp_thread_cond_t mIdleCond; 36 | sp_thread_cond_t mFullCond; 37 | sp_thread_cond_t mEmptyCond; 38 | 39 | SP_Thread_t ** mThreadList; 40 | 41 | static sp_thread_result_t SP_THREAD_CALL wrapperFunc( void * ); 42 | int saveThread( SP_Thread_t * thread ); 43 | }; 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /spserver/sputils.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __sputils_hpp__ 7 | #define __sputils_hpp__ 8 | 9 | #include "spthread.hpp" 10 | 11 | class SP_ArrayList { 12 | public: 13 | static const int LAST_INDEX; 14 | 15 | SP_ArrayList( int initCount = 2 ); 16 | virtual ~SP_ArrayList(); 17 | 18 | int getCount() const; 19 | int append( void * value ); 20 | const void * getItem( int index ) const; 21 | void * takeItem( int index ); 22 | 23 | void clean(); 24 | 25 | private: 26 | SP_ArrayList( SP_ArrayList & ); 27 | SP_ArrayList & operator=( SP_ArrayList & ); 28 | 29 | int mMaxCount; 30 | int mCount; 31 | void ** mFirst; 32 | }; 33 | 34 | class SP_CircleQueue { 35 | public: 36 | SP_CircleQueue(); 37 | virtual ~SP_CircleQueue(); 38 | 39 | void push( void * item ); 40 | void * pop(); 41 | void * top(); 42 | int getLength(); 43 | 44 | private: 45 | void ** mEntries; 46 | unsigned int mHead; 47 | unsigned int mTail; 48 | unsigned int mCount; 49 | unsigned int mMaxCount; 50 | }; 51 | 52 | class SP_BlockingQueue { 53 | public: 54 | SP_BlockingQueue(); 55 | virtual ~SP_BlockingQueue(); 56 | 57 | // non-blocking 58 | void push( void * item ); 59 | 60 | // blocking until can pop 61 | void * pop(); 62 | 63 | // non-blocking, if empty then return NULL 64 | void * top(); 65 | 66 | // non-blocking 67 | int getLength(); 68 | 69 | private: 70 | SP_CircleQueue * mQueue; 71 | sp_thread_mutex_t mMutex; 72 | sp_thread_cond_t mCond; 73 | }; 74 | 75 | int sp_strtok( const char * src, int index, char * dest, int len, 76 | char delimiter = ' ', const char ** next = 0 ); 77 | 78 | char * sp_strlcpy( char * dest, const char * src, int n ); 79 | 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /spserver/spwin32iocp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spwin32iocp_hpp__ 7 | #define __spwin32iocp_hpp__ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "spiocpevent.hpp" 15 | 16 | class SP_HandlerFactory; 17 | class SP_IOChannelFactory; 18 | class SP_Session; 19 | class SP_Message; 20 | class SP_Response; 21 | 22 | typedef struct tagSP_IocpAcceptArg { 23 | SP_HandlerFactory * mHandlerFactory; 24 | SP_IOChannelFactory * mIOChannelFactory; 25 | 26 | int mReqQueueSize; 27 | int mMaxConnections; 28 | char * mRefusedMsg; 29 | 30 | // per handle data 31 | SP_IocpEventArg * mEventArg; 32 | HANDLE mListenSocket; 33 | 34 | // per io data 35 | OVERLAPPED mOverlapped; 36 | HANDLE mClientSocket; 37 | char mBuffer[ 1024 ]; 38 | 39 | HANDLE mAcceptEvent; 40 | } SP_IocpAcceptArg_t; 41 | 42 | typedef struct tagSP_IocpSession { 43 | SP_Session * mSession; 44 | SP_IocpEventArg * mEventArg; 45 | 46 | HANDLE mHandle; 47 | 48 | SP_IocpEvent_t mRecvEvent; 49 | SP_IocpEvent_t mSendEvent; 50 | OVERLAPPED mFreeEvent; 51 | } SP_IocpSession_t; 52 | 53 | class SP_IocpEventCallback { 54 | public: 55 | 56 | enum { eKeyUnknown, eKeyAccept, eKeyMsgQueue, eKeyFree }; 57 | 58 | static BOOL addSession( SP_IocpEventArg * eventArg, HANDLE client, SP_Session * session ); 59 | static BOOL addRecv( SP_Session * session ); 60 | static BOOL addSend( SP_Session * session ); 61 | 62 | static void onRecv( SP_IocpSession_t * iocpSession ); 63 | static void onSend( SP_IocpSession_t * iocpSession ); 64 | static BOOL onAccept( SP_IocpAcceptArg_t * acceptArg ); 65 | static void onResponse( void * queueData, void * arg ); 66 | 67 | static void onTimeout( SP_IocpEventArg * eventArg ); 68 | 69 | static BOOL eventLoop( SP_IocpEventArg * eventArg, SP_IocpAcceptArg_t * acceptArg ); 70 | 71 | private: 72 | SP_IocpEventCallback(); 73 | ~SP_IocpEventCallback(); 74 | }; 75 | 76 | typedef struct tagSP_Sid SP_Sid_t; 77 | 78 | class SP_IocpEventHelper { 79 | public: 80 | static void doStart( SP_Session * session ); 81 | static void start( void * arg ); 82 | 83 | static void doWork( SP_Session * session ); 84 | static void worker( void * arg ); 85 | 86 | static void doError( SP_Session * session ); 87 | static void error( void * arg ); 88 | 89 | static void doTimeout( SP_Session * session ); 90 | static void timeout( void * arg ); 91 | 92 | static void doClose( SP_Session * session ); 93 | static void close( void * arg ); 94 | 95 | static void doDecodeForWork( SP_Session * session ); 96 | 97 | static void doCompletion( SP_IocpEventArg * eventArg, SP_Message * msg ); 98 | 99 | static int isSystemSid( SP_Sid_t * sid ); 100 | 101 | static DWORD timeoutNext( SP_IocpEventHeap * eventHeap ); 102 | 103 | private: 104 | SP_IocpEventHelper(); 105 | ~SP_IocpEventHelper(); 106 | }; 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /spserver/spwin32port.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spwin32port_hpp__ 7 | #define __spwin32port_hpp__ 8 | 9 | #pragma warning(disable: 4996) 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | typedef unsigned short uint16_t; 21 | typedef unsigned __int64 uint64_t; 22 | typedef int socklen_t; 23 | 24 | #ifndef WSAID_DISCONNECTEX 25 | #define WSAID_DISCONNECTEX {0x7fda2e11,0x8630,0x436f,{0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}} 26 | typedef BOOL (WINAPI *LPFN_DISCONNECTEX)(SOCKET, LPOVERLAPPED, DWORD, DWORD); 27 | #endif 28 | 29 | #if _MSC_VER >= 1400 30 | #define localtime_r(_clock, _result) localtime_s(_result, _clock) 31 | #define gmtime_r(_clock, _result) gmtime_s(_result, _clock) 32 | #define strcasecmp _stricmp 33 | #define strncasecmp _strnicmp 34 | #else 35 | #define localtime_r(_clock, _result) ( *(_result) = *localtime( (_clock) ), (_result) ) 36 | #define gmtime_r(_clock, _result) ( *(_result) = *gmtime( (_clock) ), (_result) ) 37 | #define strcasecmp stricmp 38 | #define strncasecmp strnicmp 39 | #endif 40 | 41 | #define snprintf _snprintf 42 | #define pause() Sleep((32767L << 16) + 32767) 43 | #define sleep(x) Sleep(x*1000) 44 | 45 | #define sp_close closesocket 46 | #define sp_writev spwin32_writev 47 | #define sp_inet_aton spwin32_inet_aton 48 | #define sp_socketpair spwin32_socketpair 49 | #define sp_initsock spwin32_initsocket 50 | #define sp_gettimeofday spwin32_gettimeofday 51 | 52 | #define sp_syslog g_spwin32_syslog 53 | #define sp_openlog spwin32_openlog 54 | #define sp_closelog spwin32_closelog 55 | #define sp_setlogmask spwin32_setlogmask 56 | 57 | /* Windows writev() support */ 58 | struct iovec 59 | { 60 | u_long iov_len; 61 | char *iov_base; 62 | }; 63 | 64 | extern int spwin32_writev(SOCKET sock, const struct iovec *vector, DWORD count); 65 | 66 | extern int spwin32_inet_aton(const char *c, struct in_addr* addr); 67 | 68 | extern int spwin32_socketpair(int d, int type, int protocol, int sv[2]); 69 | 70 | /* @return >0 OK, 0 FAIL */ 71 | extern DWORD spwin32_getppid(void); 72 | 73 | /* @return 0 OK, -1 Fail*/ 74 | extern int spwin32_getexefile( DWORD pid, char * path, int size ); 75 | 76 | extern const char * spwin32_strerror( DWORD lastError, char * errmsg, size_t len ); 77 | 78 | extern void spwin32_pwd( char * path, int size ); 79 | 80 | /* @return 0 OK, -1 Fail */ 81 | extern int spwin32_initsocket(); 82 | 83 | extern void spwin32_pause_console(); 84 | 85 | extern int spwin32_gettimeofday(struct timeval* tv, void * ); 86 | 87 | /* Windows syslog() support */ 88 | 89 | #define LOG_EMERG 0 90 | #define LOG_ALERT 1 91 | #define LOG_CRIT 2 92 | #define LOG_ERR 3 93 | #define LOG_WARNING 4 94 | #define LOG_NOTICE 5 95 | #define LOG_INFO 6 96 | #define LOG_DEBUG 7 97 | 98 | /* 99 | * Option flags for openlog. 100 | * 101 | * LOG_ODELAY no longer does anything. 102 | * LOG_NDELAY is the inverse of what it used to be. 103 | */ 104 | #define LOG_PID 0x01 /* log the pid with each message */ 105 | #define LOG_CONS 0x02 /* log on the console if errors in sending */ 106 | #define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ 107 | #define LOG_NDELAY 0x08 /* don't delay open */ 108 | #define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ 109 | #define LOG_PERROR 0x20 /* log to stderr as well */ 110 | 111 | #define LOG_USER (1<<3) 112 | 113 | extern void spwin32_syslog (int priority, const char * format, ...); 114 | extern void spwin32_closelog (void); 115 | extern void spwin32_openlog (const char *ident , int option , int facility); 116 | extern int spwin32_setlogmask (int priority); 117 | 118 | typedef void ( * spwin32_logger_t ) ( int priority, const char * format, ... ); 119 | 120 | /* default is spwin32_syslog, write to stdout */ 121 | extern spwin32_logger_t g_spwin32_syslog; 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /spserver/testdispatcher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "spdispatcher.hpp" 17 | #include "sphandler.hpp" 18 | #include "spresponse.hpp" 19 | #include "sprequest.hpp" 20 | #include "spbuffer.hpp" 21 | #include "spmsgdecoder.hpp" 22 | #include "speventcb.hpp" 23 | #include "spioutils.hpp" 24 | 25 | class SP_EchoHandler : public SP_Handler { 26 | public: 27 | SP_EchoHandler(){} 28 | virtual ~SP_EchoHandler(){} 29 | 30 | // return -1 : terminate session, 0 : continue 31 | virtual int start( SP_Request * request, SP_Response * response ) { 32 | request->setMsgDecoder( new SP_LineMsgDecoder() ); 33 | response->getReply()->getMsg()->append( 34 | "Welcome to line echo dispatcher, enter 'quit' to quit.\r\n" ); 35 | 36 | return 0; 37 | } 38 | 39 | // return -1 : terminate session, 0 : continue 40 | virtual int handle( SP_Request * request, SP_Response * response ) { 41 | SP_LineMsgDecoder * decoder = (SP_LineMsgDecoder*)request->getMsgDecoder(); 42 | 43 | if( 0 != strcasecmp( (char*)decoder->getMsg(), "quit" ) ) { 44 | response->getReply()->getMsg()->append( (char*)decoder->getMsg() ); 45 | response->getReply()->getMsg()->append( "\r\n" ); 46 | return 0; 47 | } else { 48 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 49 | return -1; 50 | } 51 | } 52 | 53 | virtual void error( SP_Response * response ) {} 54 | 55 | virtual void timeout( SP_Response * response ) {} 56 | 57 | virtual void close() {} 58 | }; 59 | 60 | class SP_EchoTimerHandler : public SP_TimerHandler { 61 | public: 62 | SP_EchoTimerHandler(){ 63 | mCount = 1; 64 | } 65 | 66 | virtual ~SP_EchoTimerHandler(){} 67 | 68 | // return -1 : terminate timer, 0 : continue 69 | virtual int handle( SP_Response * response, struct timeval * timeout ) { 70 | syslog( LOG_NOTICE, "time = %li, call timer handler", time( NULL ) ); 71 | 72 | if( ++mCount >= 10 ) { 73 | syslog( LOG_NOTICE, "stop timer" ); 74 | return -1; 75 | } else { 76 | syslog( LOG_NOTICE, "set timer to %d seconds later", mCount ); 77 | timeout->tv_sec = mCount; 78 | return 0; 79 | } 80 | } 81 | 82 | private: 83 | int mCount; 84 | }; 85 | 86 | int main( int argc, char * argv[] ) 87 | { 88 | int port = 3333, maxThreads = 10; 89 | 90 | extern char *optarg ; 91 | int c ; 92 | 93 | while( ( c = getopt ( argc, argv, "p:t:v" )) != EOF ) { 94 | switch ( c ) { 95 | case 'p' : 96 | port = atoi( optarg ); 97 | break; 98 | case 't': 99 | maxThreads = atoi( optarg ); 100 | break; 101 | case '?' : 102 | case 'v' : 103 | printf( "Usage: %s [-p ] [-t ]\n", argv[0] ); 104 | exit( 0 ); 105 | } 106 | } 107 | 108 | openlog( "testdispatcher", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 109 | 110 | int maxConnections = 100, reqQueueSize = 10; 111 | const char * refusedMsg = "System busy, try again later."; 112 | 113 | int listenFd = -1; 114 | if( 0 == SP_IOUtils::tcpListen( "", port, &listenFd ) ) { 115 | SP_Dispatcher dispatcher( new SP_DefaultCompletionHandler(), maxThreads ); 116 | dispatcher.dispatch(); 117 | 118 | struct timeval timeout; 119 | memset( &timeout, 0, sizeof( timeout ) ); 120 | timeout.tv_sec = 1; 121 | 122 | dispatcher.push( &timeout, new SP_EchoTimerHandler() ); 123 | 124 | for( ; ; ) { 125 | struct sockaddr_in addr; 126 | socklen_t socklen = sizeof( addr ); 127 | int fd = accept( listenFd, (struct sockaddr*)&addr, &socklen ); 128 | 129 | if( fd > 0 ) { 130 | if( dispatcher.getSessionCount() >= maxConnections 131 | || dispatcher.getReqQueueLength() >= reqQueueSize ) { 132 | write( fd, refusedMsg, strlen( refusedMsg ) ); 133 | close( fd ); 134 | } else { 135 | dispatcher.push( fd, new SP_EchoHandler() ); 136 | } 137 | } else { 138 | break; 139 | } 140 | } 141 | } 142 | 143 | closelog(); 144 | 145 | return 0; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /spserver/testecho.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "spporting.hpp" 13 | 14 | #include "spmsgdecoder.hpp" 15 | #include "spbuffer.hpp" 16 | 17 | #include "spserver.hpp" 18 | #include "sphandler.hpp" 19 | #include "spresponse.hpp" 20 | #include "sprequest.hpp" 21 | #include "sputils.hpp" 22 | 23 | class SP_EchoHandler : public SP_Handler { 24 | public: 25 | SP_EchoHandler(){} 26 | virtual ~SP_EchoHandler(){} 27 | 28 | // return -1 : terminate session, 0 : continue 29 | virtual int start( SP_Request * request, SP_Response * response ) { 30 | request->setMsgDecoder( new SP_MultiLineMsgDecoder() ); 31 | response->getReply()->getMsg()->append( 32 | "Welcome to line echo server, enter 'quit' to quit.\r\n" ); 33 | 34 | return 0; 35 | } 36 | 37 | // return -1 : terminate session, 0 : continue 38 | virtual int handle( SP_Request * request, SP_Response * response ) { 39 | SP_MultiLineMsgDecoder * decoder = (SP_MultiLineMsgDecoder*)request->getMsgDecoder(); 40 | SP_CircleQueue * queue = decoder->getQueue(); 41 | 42 | int ret = 0; 43 | for( ; NULL != queue->top(); ) { 44 | char * line = (char*)queue->pop(); 45 | 46 | if( 0 != strcasecmp( line, "quit" ) ) { 47 | response->getReply()->getMsg()->append( line ); 48 | response->getReply()->getMsg()->append( "\r\n" ); 49 | } else { 50 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 51 | ret = -1; 52 | } 53 | 54 | free( line ); 55 | } 56 | 57 | return ret; 58 | } 59 | 60 | virtual void error( SP_Response * response ) {} 61 | 62 | virtual void timeout( SP_Response * response ) {} 63 | 64 | virtual void close() {} 65 | }; 66 | 67 | class SP_EchoHandlerFactory : public SP_HandlerFactory { 68 | public: 69 | SP_EchoHandlerFactory() {} 70 | virtual ~SP_EchoHandlerFactory() {} 71 | 72 | virtual SP_Handler * create() const { 73 | return new SP_EchoHandler(); 74 | } 75 | }; 76 | 77 | //--------------------------------------------------------- 78 | 79 | int main( int argc, char * argv[] ) 80 | { 81 | sp_openlog( "testecho", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 82 | 83 | int port = 3333; 84 | 85 | assert( 0 == sp_initsock() ); 86 | 87 | SP_Server server( "", port, new SP_EchoHandlerFactory() ); 88 | server.setMaxConnections( 10000 ); 89 | server.setReqQueueSize( 10000, "Server busy!" ); 90 | server.runForever(); 91 | 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /spserver/testhttp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spporting.hpp" 14 | 15 | #include "sphttp.hpp" 16 | #include "sphttpmsg.hpp" 17 | #include "spserver.hpp" 18 | #include "splfserver.hpp" 19 | 20 | class SP_HttpEchoHandler : public SP_HttpHandler { 21 | public: 22 | SP_HttpEchoHandler(){} 23 | virtual ~SP_HttpEchoHandler(){} 24 | 25 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) { 26 | response->setStatusCode( 200 ); 27 | response->appendContent( "" 28 | "Welcome to simple http" 29 | "" ); 30 | 31 | char buffer[ 512 ] = { 0 }; 32 | snprintf( buffer, sizeof( buffer ), 33 | "

The requested URI is : %s.

", request->getURI() ); 34 | response->appendContent( buffer ); 35 | 36 | snprintf( buffer, sizeof( buffer ), 37 | "

Client IP is : %s.

", request->getClientIP() ); 38 | response->appendContent( buffer ); 39 | 40 | int i = 0; 41 | 42 | for( i = 0; i < request->getParamCount(); i++ ) { 43 | snprintf( buffer, sizeof( buffer ), 44 | "

Param - %s = %s

", request->getParamName( i ), request->getParamValue( i ) ); 45 | response->appendContent( buffer ); 46 | } 47 | 48 | for( i = 0; i < request->getHeaderCount(); i++ ) { 49 | snprintf( buffer, sizeof( buffer ), 50 | "

Header - %s: %s

", request->getHeaderName( i ), request->getHeaderValue( i ) ); 51 | response->appendContent( buffer ); 52 | } 53 | 54 | if( NULL != request->getContent() ) { 55 | response->appendContent( "

" ); 56 | response->appendContent( request->getContent(), request->getContentLength() ); 57 | response->appendContent( "

" ); 58 | } 59 | 60 | response->appendContent( "\n" ); 61 | } 62 | }; 63 | 64 | class SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory { 65 | public: 66 | SP_HttpEchoHandlerFactory(){} 67 | virtual ~SP_HttpEchoHandlerFactory(){} 68 | 69 | virtual SP_HttpHandler * create() const { 70 | return new SP_HttpEchoHandler(); 71 | } 72 | }; 73 | 74 | int main( int argc, char * argv[] ) 75 | { 76 | int port = 8080, maxThreads = 10; 77 | const char * serverType = "lf"; 78 | 79 | #ifndef WIN32 80 | extern char *optarg ; 81 | int c ; 82 | 83 | while( ( c = getopt ( argc, argv, "p:t:s:v" )) != EOF ) { 84 | switch ( c ) { 85 | case 'p' : 86 | port = atoi( optarg ); 87 | break; 88 | case 't': 89 | maxThreads = atoi( optarg ); 90 | break; 91 | case 's': 92 | serverType = optarg; 93 | break; 94 | case '?' : 95 | case 'v' : 96 | printf( "Usage: %s [-p ] [-t ] [-s ]\n", argv[0] ); 97 | exit( 0 ); 98 | } 99 | } 100 | #endif 101 | 102 | sp_openlog( "testhttp", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 103 | 104 | assert( 0 == sp_initsock() ); 105 | 106 | if( 0 == strcasecmp( serverType, "hahs" ) ) { 107 | SP_Server server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 108 | 109 | server.setTimeout( 60 ); 110 | server.setMaxThreads( maxThreads ); 111 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 112 | 113 | server.runForever(); 114 | } else { 115 | SP_LFServer server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 116 | 117 | server.setTimeout( 60 ); 118 | server.setMaxThreads( maxThreads ); 119 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 120 | 121 | server.runForever(); 122 | } 123 | 124 | sp_closelog(); 125 | 126 | return 0; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /spserver/testhttp_d.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spporting.hpp" 14 | 15 | #include "sphttp.hpp" 16 | #include "sphttpmsg.hpp" 17 | #include "spdispatcher.hpp" 18 | #include "spioutils.hpp" 19 | 20 | class SP_HttpEchoHandler : public SP_HttpHandler { 21 | public: 22 | SP_HttpEchoHandler(){} 23 | virtual ~SP_HttpEchoHandler(){} 24 | 25 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) { 26 | response->setStatusCode( 200 ); 27 | response->appendContent( "" 28 | "Welcome to simple http" 29 | "" ); 30 | 31 | char buffer[ 512 ] = { 0 }; 32 | snprintf( buffer, sizeof( buffer ), 33 | "

The requested URI is : %s.

", request->getURI() ); 34 | response->appendContent( buffer ); 35 | 36 | snprintf( buffer, sizeof( buffer ), 37 | "

Client IP is : %s.

", request->getClientIP() ); 38 | response->appendContent( buffer ); 39 | 40 | int i = 0; 41 | 42 | for( i = 0; i < request->getParamCount(); i++ ) { 43 | snprintf( buffer, sizeof( buffer ), 44 | "

Param - %s = %s

", request->getParamName( i ), request->getParamValue( i ) ); 45 | response->appendContent( buffer ); 46 | } 47 | 48 | for( i = 0; i < request->getHeaderCount(); i++ ) { 49 | snprintf( buffer, sizeof( buffer ), 50 | "

Header - %s: %s

", request->getHeaderName( i ), request->getHeaderValue( i ) ); 51 | response->appendContent( buffer ); 52 | } 53 | 54 | if( NULL != request->getContent() ) { 55 | response->appendContent( "

" ); 56 | response->appendContent( request->getContent(), request->getContentLength() ); 57 | response->appendContent( "

" ); 58 | } 59 | 60 | response->appendContent( "\n" ); 61 | } 62 | }; 63 | 64 | class SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory { 65 | public: 66 | SP_HttpEchoHandlerFactory(){} 67 | virtual ~SP_HttpEchoHandlerFactory(){} 68 | 69 | virtual SP_HttpHandler * create() const { 70 | return new SP_HttpEchoHandler(); 71 | } 72 | }; 73 | 74 | int main( int argc, char * argv[] ) 75 | { 76 | int port = 8080, maxThreads = 10; 77 | 78 | extern char *optarg ; 79 | int c ; 80 | 81 | while( ( c = getopt ( argc, argv, "p:t:v" )) != EOF ) { 82 | switch ( c ) { 83 | case 'p' : 84 | port = atoi( optarg ); 85 | break; 86 | case 't': 87 | maxThreads = atoi( optarg ); 88 | break; 89 | case '?' : 90 | case 'v' : 91 | printf( "Usage: %s [-p ] [-t ]\n", argv[0] ); 92 | exit( 0 ); 93 | } 94 | } 95 | 96 | //openlog( "testhttp_d", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 97 | 98 | int maxConnections = 10000, reqQueueSize = 10000; 99 | const char * refusedMsg = "HTTP/1.1 500 Sorry, server is busy now!\r\n"; 100 | 101 | SP_HttpHandlerAdapterFactory factory( new SP_HttpEchoHandlerFactory() ); 102 | 103 | int listenFd = -1; 104 | if( 0 == SP_IOUtils::tcpListen( "", port, &listenFd ) ) { 105 | SP_Dispatcher dispatcher( new SP_DefaultCompletionHandler(), maxThreads ); 106 | dispatcher.dispatch(); 107 | dispatcher.setTimeout( 60 ); 108 | 109 | for( ; ; ) { 110 | struct sockaddr_in addr; 111 | socklen_t socklen = sizeof( addr ); 112 | int fd = accept( listenFd, (struct sockaddr*)&addr, &socklen ); 113 | 114 | if( fd > 0 ) { 115 | if( dispatcher.getSessionCount() >= maxConnections 116 | || dispatcher.getReqQueueLength() >= reqQueueSize ) { 117 | write( fd, refusedMsg, strlen( refusedMsg ) ); 118 | close( fd ); 119 | } else { 120 | dispatcher.push( fd, factory.create() ); 121 | } 122 | } else { 123 | break; 124 | } 125 | } 126 | } 127 | 128 | closelog(); 129 | 130 | return 0; 131 | } 132 | 133 | -------------------------------------------------------------------------------- /spserver/testhttpmsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "sphttpmsg.hpp" 12 | 13 | void printMessage( SP_HttpMessage * message ) 14 | { 15 | for( int i = 0; i < message->getHeaderCount(); i++ ) { 16 | printf( "%s: %s\n", message->getHeaderName( i ), message->getHeaderValue( i ) ); 17 | } 18 | printf( "\n" ); 19 | 20 | if( NULL != message->getContent() ) { 21 | printf( "%s", (char*)message->getContent() ); 22 | } 23 | 24 | printf( "\n" ); 25 | } 26 | 27 | void printRequest( SP_HttpRequest * request ) 28 | { 29 | printf( "%s %s %s\n", request->getMethod(), request->getURI(), request->getVersion() ); 30 | 31 | for( int i = 0; i < request->getParamCount(); i++ ) { 32 | printf( "Param: %s=%s\n", request->getParamName(i), request->getParamValue(i) ); 33 | } 34 | 35 | printMessage( request ); 36 | } 37 | 38 | void printResponse( SP_HttpResponse * response ) 39 | { 40 | printf( "%s %d %s\n", response->getVersion(), response->getStatusCode(), 41 | response->getReasonPhrase() ); 42 | printMessage( response ); 43 | } 44 | 45 | int main( int argc, char * argv[] ) 46 | { 47 | char * filename = NULL; 48 | 49 | if( argc < 2 ) { 50 | printf( "Usage: %s \n", argv[0] ); 51 | exit( -1 ); 52 | } else { 53 | filename = argv[1]; 54 | } 55 | 56 | FILE * fp = fopen ( filename, "r" ); 57 | if( NULL == fp ) { 58 | printf( "cannot not open %s\n", filename ); 59 | exit( -1 ); 60 | } 61 | 62 | struct stat aStat; 63 | char * source = NULL; 64 | stat( filename, &aStat ); 65 | source = ( char * ) malloc ( aStat.st_size + 1 ); 66 | fread ( source, aStat.st_size, sizeof ( char ), fp ); 67 | fclose ( fp ); 68 | source[ aStat.st_size ] = 0; 69 | 70 | SP_HttpMsgParser parser; 71 | //parser.setIgnoreContent( 1 ); 72 | 73 | int parsedLen = 0; 74 | for( int i = 0; i < (int)strlen( source ); i++ ) { 75 | parsedLen += parser.append( source + parsedLen, i - parsedLen + 1 ); 76 | //printf( "%d, %d\n", i, parsedLen ); 77 | } 78 | 79 | printf( "source length : %d, parsed length : %d\n", strlen( source ), parsedLen ); 80 | 81 | printf( "parse complete : %s\n", parser.isCompleted() ? "Yes" : "No" ); 82 | 83 | printf( "ignore content: %s\n", parser.isIgnoreContent() ? "Yes" : "No" ); 84 | 85 | puts( "\n" ); 86 | 87 | if( NULL != parser.getRequest() ) { 88 | printRequest( parser.getRequest() ); 89 | } 90 | 91 | if( NULL != parser.getResponse() ) { 92 | printResponse( parser.getResponse() ); 93 | } 94 | 95 | free( source ); 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /spserver/testiocphttp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define _CRTDBG_MAP_ALLOC 12 | #include 13 | #include 14 | 15 | #include "spporting.hpp" 16 | 17 | #include "spwin32iocp.hpp" 18 | #include "spiocpserver.hpp" 19 | 20 | #include "sphttp.hpp" 21 | #include "sphttpmsg.hpp" 22 | #include "spserver.hpp" 23 | 24 | #pragma comment(lib,"ws2_32") 25 | #pragma comment(lib,"mswsock") 26 | 27 | class SP_HttpEchoHandler : public SP_HttpHandler { 28 | public: 29 | SP_HttpEchoHandler(){} 30 | virtual ~SP_HttpEchoHandler(){} 31 | 32 | virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) { 33 | response->setStatusCode( 200 ); 34 | response->appendContent( "" 35 | "Welcome to simple http" 36 | "" ); 37 | 38 | char buffer[ 512 ] = { 0 }; 39 | snprintf( buffer, sizeof( buffer ), 40 | "

The requested URI is : %s.

", request->getURI() ); 41 | response->appendContent( buffer ); 42 | 43 | snprintf( buffer, sizeof( buffer ), 44 | "

Client IP is : %s.

", request->getClientIP() ); 45 | response->appendContent( buffer ); 46 | 47 | int i = 0; 48 | 49 | for( i = 0; i < request->getParamCount(); i++ ) { 50 | snprintf( buffer, sizeof( buffer ), 51 | "

Param - %s = %s

", request->getParamName( i ), request->getParamValue( i ) ); 52 | response->appendContent( buffer ); 53 | } 54 | 55 | for( i = 0; i < request->getHeaderCount(); i++ ) { 56 | snprintf( buffer, sizeof( buffer ), 57 | "

Header - %s: %s

", request->getHeaderName( i ), request->getHeaderValue( i ) ); 58 | response->appendContent( buffer ); 59 | } 60 | 61 | if( NULL != request->getContent() ) { 62 | response->appendContent( "

" ); 63 | response->appendContent( request->getContent(), request->getContentLength() ); 64 | response->appendContent( "

" ); 65 | } 66 | 67 | response->appendContent( "\n" ); 68 | } 69 | }; 70 | 71 | class SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory { 72 | public: 73 | SP_HttpEchoHandlerFactory(){} 74 | virtual ~SP_HttpEchoHandlerFactory(){} 75 | 76 | virtual SP_HttpHandler * create() const { 77 | return new SP_HttpEchoHandler(); 78 | } 79 | }; 80 | 81 | int main( int argc, char * argv[] ) 82 | { 83 | int port = 8080, maxThreads = 10; 84 | const char * serverType = "hahs"; 85 | 86 | if( 0 != sp_initsock() ) assert( 0 ); 87 | 88 | SP_IocpServer server( "", port, new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) ); 89 | 90 | server.setTimeout( 60 ); 91 | server.setMaxThreads( maxThreads ); 92 | server.setReqQueueSize( 100, "HTTP/1.1 500 Sorry, server is busy now!\r\n" ); 93 | 94 | server.runForever(); 95 | 96 | sp_closelog(); 97 | 98 | return 0; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /spserver/testthreadpool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "spthread.hpp" 12 | 13 | #include "spporting.hpp" 14 | 15 | #include "spthreadpool.hpp" 16 | 17 | extern int errno; 18 | 19 | void threadFunc( void *arg ) 20 | { 21 | int seconds = (int) arg; 22 | 23 | fprintf( stdout, " in threadFunc %d\n", seconds ); 24 | fprintf( stdout, " thread#%ld\n", sp_thread_self() ); 25 | sleep( seconds ); 26 | fprintf( stdout, " done threadFunc %d\n", seconds); 27 | } 28 | 29 | int main( int argc, char ** argv ) 30 | { 31 | SP_ThreadPool pool( 2 ); 32 | 33 | fprintf( stdout, "**main** dispatch 3\n" ); 34 | pool.dispatch( threadFunc, (void*)3 ); 35 | fprintf( stdout, "**main** dispatch 6\n"); 36 | pool.dispatch( threadFunc, (void*)6 ); 37 | fprintf( stdout, "**main** dispatch 7\n"); 38 | pool.dispatch( threadFunc, (void*)7 ); 39 | 40 | fprintf( stdout, "**main** done first\n" ); 41 | sleep( 20 ); 42 | fprintf( stdout, "\n\n" ); 43 | 44 | fprintf( stdout, "**main** dispatch 3\n" ); 45 | pool.dispatch( threadFunc, (void *) 3 ); 46 | fprintf( stdout, "**main** dispatch 6\n" ); 47 | pool.dispatch( threadFunc, (void *) 6 ); 48 | fprintf( stdout, "**main** dispatch 7\n"); 49 | pool.dispatch( threadFunc, (void *) 7 ); 50 | 51 | fprintf( stdout, "**main done second\n" ); 52 | 53 | sleep(20); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /spserver/testunp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spmsgdecoder.hpp" 14 | #include "spbuffer.hpp" 15 | 16 | #include "spserver.hpp" 17 | #include "splfserver.hpp" 18 | #include "sphandler.hpp" 19 | #include "spresponse.hpp" 20 | #include "sprequest.hpp" 21 | 22 | #define MAXN 16384 /* max # bytes client can request */ 23 | #define MAXLINE 4096 /* max text line length */ 24 | 25 | class SP_UnpHandler : public SP_Handler { 26 | public: 27 | SP_UnpHandler(){} 28 | virtual ~SP_UnpHandler(){} 29 | 30 | // return -1 : terminate session, 0 : continue 31 | virtual int start( SP_Request * request, SP_Response * response ) { 32 | request->setMsgDecoder( new SP_LineMsgDecoder() ); 33 | return 0; 34 | } 35 | 36 | // return -1 : terminate session, 0 : continue 37 | virtual int handle( SP_Request * request, SP_Response * response ) { 38 | SP_LineMsgDecoder * decoder = (SP_LineMsgDecoder*)request->getMsgDecoder(); 39 | 40 | int ntowrite = atol( (char*)decoder->getMsg() ); 41 | 42 | if ((ntowrite <= 0) || (ntowrite > MAXN)) { 43 | syslog( LOG_WARNING, "WARN: client request for %d bytes", ntowrite ); 44 | return -1; 45 | } 46 | 47 | char result[ MAXN ]; 48 | 49 | response->getReply()->getMsg()->append( result, ntowrite ); 50 | 51 | return -1; 52 | } 53 | 54 | virtual void error( SP_Response * response ) {} 55 | 56 | virtual void timeout( SP_Response * response ) {} 57 | 58 | virtual void close() {} 59 | }; 60 | 61 | class SP_UnpHandlerFactory : public SP_HandlerFactory { 62 | public: 63 | SP_UnpHandlerFactory() {} 64 | virtual ~SP_UnpHandlerFactory() {} 65 | 66 | virtual SP_Handler * create() const { 67 | return new SP_UnpHandler(); 68 | } 69 | }; 70 | 71 | //--------------------------------------------------------- 72 | 73 | int main( int argc, char * argv[] ) 74 | { 75 | int port = 1770, maxThreads = 10; 76 | const char * serverType = "lf"; 77 | 78 | extern char *optarg ; 79 | int c ; 80 | 81 | while( ( c = getopt ( argc, argv, "p:t:s:v" )) != EOF ) { 82 | switch ( c ) { 83 | case 'p' : 84 | port = atoi( optarg ); 85 | break; 86 | case 't': 87 | maxThreads = atoi( optarg ); 88 | break; 89 | case 's': 90 | serverType = optarg; 91 | break; 92 | case '?' : 93 | case 'v' : 94 | printf( "Usage: %s [-p ] [-t ] [-s ]\n", argv[0] ); 95 | exit( 0 ); 96 | } 97 | } 98 | 99 | openlog( "testunp", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 100 | 101 | setlogmask( LOG_UPTO( LOG_WARNING ) ); 102 | 103 | if( 0 == strcasecmp( serverType, "hahs" ) ) { 104 | SP_Server server( "", port, new SP_UnpHandlerFactory() ); 105 | 106 | server.setTimeout( 60 ); 107 | server.setMaxThreads( maxThreads ); 108 | server.setReqQueueSize( 100, "Sorry, server is busy now!\r\n" ); 109 | 110 | server.runForever(); 111 | } else { 112 | SP_LFServer server( "", port, new SP_UnpHandlerFactory() ); 113 | 114 | server.setTimeout( 60 ); 115 | server.setMaxThreads( maxThreads ); 116 | server.setReqQueueSize( 100, "Sorry, server is busy now!\r\n" ); 117 | 118 | server.runForever(); 119 | } 120 | 121 | closelog(); 122 | 123 | return 0; 124 | } 125 | 126 | -------------------------------------------------------------------------------- /sptunnel/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread -lresolv 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | ifeq ($(origin ssl), undefined) 15 | ssl = openssl 16 | endif 17 | 18 | ifeq ($(ssl), openssl) 19 | CFLAGS += -DOPENSSL 20 | SSL_INCL = -I../openssl 21 | SSL_LIB = -L../openssl -lspopenssl -lssl -lcrypto 22 | else 23 | CFLAGS += -DMATRIXSSL 24 | SSL_INCL = -I../matrixssl 25 | SSL_LIB = -L../matrixssl -lspmatrixssl -lmatrixssl 26 | endif 27 | 28 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 29 | 30 | SPSERVER_INCL = -I../spserver 31 | SPSERVER_LIB = -L../spserver -lspserver 32 | 33 | CFLAGS += $(SSL_INCL) $(SPSERVER_INCL) 34 | LDFLAGS += $(LIBEVENT_LIB) $(SSL_LIB) $(SPSERVER_LIB) 35 | 36 | #-------------------------------------------------------------------- 37 | 38 | TARGET = sptunnel 39 | 40 | #-------------------------------------------------------------------- 41 | 42 | all: $(TARGET) 43 | 44 | sptunnel: sptunnelimpl.o sptunnel.o 45 | $(LINKER) $(LDFLAGS) $^ -o $@ 46 | 47 | clean: 48 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 49 | 50 | #-------------------------------------------------------------------- 51 | 52 | # make rule 53 | %.o : %.c 54 | $(CC) $(CFLAGS) -c $^ -o $@ 55 | 56 | %.o : %.cpp 57 | $(CC) $(CFLAGS) -c $^ -o $@ 58 | 59 | -------------------------------------------------------------------------------- /sptunnel/README: -------------------------------------------------------------------------------- 1 | sptunnel README 2 | 3 | The sptunnel program is designed to work as an SSL encryption wrapper 4 | between remote client and local or remote server. It can be used to 5 | add SSL functionality to commonly daemons like POP2, POP3, IMAP and HTTP 6 | servers without any changes in the programs' code. 7 | 8 | bash-2.05a$ ./sptunnel -v 9 | Usage: ./sptunnel [-p ] [-t ] [-r ] 10 | 11 | bash-2.05a$ ./sptunnel 12 | sptunnel[27626]: Backend server - 66.249.89.99:80 ;; default is google.com 13 | sptunnel[27626]: Listen on port [8080] 14 | 15 | You can use the browser ( IE, Firefox, etc. ) to visit: 16 | 17 | https://:8008/ 18 | 19 | Or, use curl 20 | 21 | curl https://:8080/ 22 | 23 | 24 | Enjoy! 25 | 26 | -- stephen liu 27 | 28 | -------------------------------------------------------------------------------- /sptunnel/demo.crt: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 2 (0x2) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=NO, ST=TEST, L=TEST, O=TEST, OU=TEST, CN=TEST/Email=TEST@TEST.COM 7 | Validity 8 | Not Before: Dec 18 02:06:26 2000 GMT 9 | Not After : Dec 18 02:06:26 2001 GMT 10 | Subject: C=NO, ST=TEST, L=TEST, O=TEST, OU=DEMO, CN=DEMO/Email=TEST@TEST.COM 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (512 bit) 14 | Modulus (512 bit): 15 | 00:c8:46:d3:a7:b5:da:58:b1:5a:08:6b:28:a8:7b: 16 | a5:9b:4a:83:1e:58:4f:0b:18:9e:aa:83:11:27:97: 17 | 24:92:70:0b:47:f4:c8:74:a1:58:92:19:35:88:b3: 18 | 8a:b4:ae:ee:e2:98:5d:bf:d4:53:b8:c6:0c:a1:da: 19 | be:b6:b2:18:f9 20 | Exponent: 65537 (0x10001) 21 | X509v3 extensions: 22 | X509v3 Basic Constraints: 23 | CA:FALSE 24 | Netscape Comment: 25 | OpenSSL Generated Certificate 26 | X509v3 Subject Key Identifier: 27 | 64:2B:31:23:69:F6:49:10:96:EB:BB:5E:91:F2:12:54:37:E6:B3:6B 28 | X509v3 Authority Key Identifier: 29 | keyid:BA:E8:35:48:75:8B:37:A9:77:48:D5:7A:B3:AB:34:C2:41:7C:FF:0E 30 | DirName:/C=NO/ST=TEST/L=TEST/O=TEST/OU=TEST/CN=TEST/Email=TEST@TEST.COM 31 | serial:00 32 | 33 | Signature Algorithm: md5WithRSAEncryption 34 | c0:36:98:cd:32:2d:65:59:60:a9:c9:ca:fa:ba:d8:d6:b1:89: 35 | 16:8b:ae:a5:6f:ea:c3:a0:b1:55:27:0b:04:42:a2:2f:33:39: 36 | fc:46:79:5d:63:33:bf:a7:b2:32:01:a7:17:13:6b:c6:67:2b: 37 | ee:ee:37:3e:64:e4:bb:5d:e9:28:5b:1b:46:33:3d:c1:27:fb: 38 | 8c:ff:ef:e5:49:22:18:e7:6a:03:4c:80:67:45:41:7c:48:e2: 39 | a8:a4:d4:7e:18:09:1d:2d:ab:bd:f0:97:ac:ba:5a:28:46:51: 40 | a0:d3:80:b2:83:70:d4:9a:a6:d0:5f:46:77:43:0e:aa:25:d3: 41 | 19:3c 42 | test haha 43 | -----BEGIN CERTIFICATE----- 44 | MIIDHTCCAoagAwIBAgIBAjANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 45 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 46 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 47 | RVNULkNPTTAeFw0wMDEyMTgwMjA2MjZaFw0wMTEyMTgwMjA2MjZaMHYxCzAJBgNV 48 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 49 | RVNUMQ0wCwYDVQQLEwRERU1PMQ0wCwYDVQQDEwRERU1PMRwwGgYJKoZIhvcNAQkB 50 | Fg1URVNUQFRFU1QuQ09NMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMhG06e12lix 51 | WghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHShWJIZNYizirSu7uKYXb/UU7jG 52 | DKHavrayGPkCAwEAAaOB/jCB+zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P 53 | cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUZCsxI2n2SRCW 54 | 67tekfISVDfms2swgaAGA1UdIwSBmDCBlYAUuug1SHWLN6l3SNV6s6s0wkF8/w6h 55 | eqR4MHYxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNU 56 | MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRww 57 | GgYJKoZIhvcNAQkBFg1URVNUQFRFU1QuQ09NggEAMA0GCSqGSIb3DQEBBAUAA4GB 58 | AMA2mM0yLWVZYKnJyvq62NaxiRaLrqVv6sOgsVUnCwRCoi8zOfxGeV1jM7+nsjIB 59 | pxcTa8ZnK+7uNz5k5Ltd6ShbG0YzPcEn+4z/7+VJIhjnagNMgGdFQXxI4qik1H4Y 60 | CR0tq73wl6y6WihGUaDTgLKDcNSaptBfRndDDqol0xk8 61 | -----END CERTIFICATE----- 62 | -------------------------------------------------------------------------------- /sptunnel/demo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIBOgIBAAJBAMhG06e12lixWghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHSh 3 | WJIZNYizirSu7uKYXb/UU7jGDKHavrayGPkCAwEAAQJAMXKzTWQr/dwEA7IZfsfQ 4 | kq/qAbMCCRZSDn1/3cuGfxT0Vd/gIXLP+yXdEC1jW1LJoBIhWQLnZHEwyKAS6OIz 5 | 0QIhAP4U3GC+SHfJ27PSGv+hjXp47QNbvvmL5T+SXqqHjqgVAiEAycn2FtiNmkzW 6 | ttLkfdZL609c49d+ac0OiTkMfBTbolUCIA9HZ901dBwn+ls85jy7FUvpG6+ZA8nz 7 | 3KxO+/xbPHvlAiB78tJ2tg5E+W3qXyB7K2b244jrazL7SjnjkGda0HUZAQIhAJVp 8 | ms+n0W3jGqEqUntQFbAfjnUo5FIZCjbiz4glt3Do 9 | -----END RSA PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /sptunnel/democa.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAp+gAwIBAgIBADANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 3 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 4 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 5 | RVNULkNPTTAeFw0wMDEyMTQwNjE2MjRaFw0wMTEyMTQwNjE2MjRaMHYxCzAJBgNV 6 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 7 | RVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRwwGgYJKoZIhvcNAQkB 8 | Fg1URVNUQFRFU1QuQ09NMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZfu/c 9 | MfHECMJDd94P0xnoKaVvSx1sR6ZUOhoExEmlOLN3vGHingNqeuhHWhfrEV3TuCJU 10 | JKuzxG/63PO1nRKl74j/14t0MRk3Mfu9xJN4VLwxsEy1v46MgAqwKk/nad7xd9kl 11 | +LPfsy2dOYGhhsO/HL2FZ3M+yPlAXQmIIcwciwIDAQABo4HTMIHQMB0GA1UdDgQW 12 | BBS66DVIdYs3qXdI1XqzqzTCQXz/DjCBoAYDVR0jBIGYMIGVgBS66DVIdYs3qXdI 13 | 1XqzqzTCQXz/DqF6pHgwdjELMAkGA1UEBhMCTk8xDTALBgNVBAgTBFRFU1QxDTAL 14 | BgNVBAcTBFRFU1QxDTALBgNVBAoTBFRFU1QxDTALBgNVBAsTBFRFU1QxDTALBgNV 15 | BAMTBFRFU1QxHDAaBgkqhkiG9w0BCQEWDVRFU1RAVEVTVC5DT02CAQAwDAYDVR0T 16 | BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQCFth61VGXHwzhy2zX7gDSSmut2RSYg 17 | 4M0a1pNkkFZjHm4Z4KN9NJQjOgBFrm1tyg+kp9eI/yY0ug4LEZ9mIVudVAluf6wV 18 | edlnf5Fs28OB/vBUR7Vew+5UET5bC3d1Etnu/h1nDLkFiM0fv2bOPkkMCXzeI08G 19 | hz7yss+W7/R7Iw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /sptunnel/sptunnel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "spporting.hpp" 13 | 14 | #include "spioutils.hpp" 15 | #include "sptunnelimpl.hpp" 16 | 17 | #ifdef OPENSSL 18 | #include "spopenssl.hpp" 19 | #else 20 | #include "spmatrixssl.hpp" 21 | #endif 22 | 23 | #ifdef WIN32 24 | #include "spgetopt.h" 25 | #include "spiocpdispatcher.hpp" 26 | #else 27 | #include "spdispatcher.hpp" 28 | #endif 29 | 30 | int main( int argc, char * argv[] ) 31 | { 32 | int port = 8080, maxThreads = 10; 33 | char * dstHost = "66.249.89.99"; 34 | int dstPort = 80; 35 | 36 | extern char *optarg ; 37 | int c ; 38 | 39 | while( ( c = getopt ( argc, argv, "p:t:r:v" )) != EOF ) { 40 | switch ( c ) { 41 | case 'p' : 42 | port = atoi( optarg ); 43 | break; 44 | case 't': 45 | maxThreads = atoi( optarg ); 46 | break; 47 | case 'r': 48 | { 49 | dstHost = strdup( optarg ); 50 | char * pos = strchr( dstHost, ':' ); 51 | if( NULL != pos ) { 52 | dstPort = atoi( pos + 1 ); 53 | *pos = '\0'; 54 | } 55 | break; 56 | } 57 | case '?' : 58 | case 'v' : 59 | printf( "Usage: %s [-p ] [-t ] [-r ]\n", argv[0] ); 60 | exit( 0 ); 61 | } 62 | } 63 | 64 | #ifdef LOG_PERROR 65 | sp_openlog( "sptunnel", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 66 | #else 67 | sp_openlog( "sptunnel", LOG_CONS | LOG_PID, LOG_USER ); 68 | #endif 69 | 70 | if( 0 != sp_initsock() ) assert( 0 ); 71 | 72 | sp_syslog( LOG_NOTICE, "Backend server - %s:%d", dstHost, dstPort ); 73 | 74 | int maxConnections = 100, reqQueueSize = 100; 75 | const char * refusedMsg = "System busy, try again later."; 76 | 77 | int listenFd = -1; 78 | if( 0 == SP_IOUtils::tcpListen( "", port, &listenFd ) ) { 79 | 80 | SP_MyDispatcher dispatcher( new SP_DefaultCompletionHandler(), maxThreads ); 81 | 82 | dispatcher.setTimeout( 60 ); 83 | dispatcher.dispatch(); 84 | 85 | #ifdef OPENSSL 86 | SP_OpensslChannelFactory * sslFactory = new SP_OpensslChannelFactory(); 87 | #else 88 | SP_MatrixsslChannelFactory * sslFactory = new SP_MatrixsslChannelFactory(); 89 | #endif 90 | 91 | #ifdef WIN32 92 | char basePath[ 256 ] = { 0 }, crtPath[ 256 ] = { 0 }, keyPath[ 256 ] = { 0 }; 93 | spwin32_pwd( basePath, sizeof( basePath ) ); 94 | snprintf( crtPath, sizeof( crtPath ), "%s\\..\\..\\..\\sptunnel\\demo.crt", basePath ); 95 | snprintf( keyPath, sizeof( keyPath ), "%s\\..\\..\\..\\sptunnel\\demo.key", basePath ); 96 | sslFactory->init( crtPath, keyPath ); 97 | #else 98 | sslFactory->init( "demo.crt", "demo.key" ); 99 | #endif 100 | 101 | for( ; ; ) { 102 | struct sockaddr_in addr; 103 | socklen_t socklen = sizeof( addr ); 104 | int fd = accept( listenFd, (struct sockaddr*)&addr, &socklen ); 105 | 106 | if( fd > 0 ) { 107 | if( dispatcher.getSessionCount() >= maxConnections 108 | || dispatcher.getReqQueueLength() >= reqQueueSize ) { 109 | write( fd, refusedMsg, strlen( refusedMsg ) ); 110 | close( fd ); 111 | } else { 112 | SP_TunnelHandler * handler = new SP_TunnelHandler( 113 | &dispatcher, dstHost, dstPort ); 114 | dispatcher.push( fd, handler, sslFactory->create() ); 115 | 116 | // for non-ssl tunnel 117 | //dispatcher.push( fd, handler, new SP_DefaultIOChannel() ); 118 | } 119 | } else { 120 | break; 121 | } 122 | } 123 | } 124 | 125 | sp_closelog(); 126 | 127 | return 0; 128 | } 129 | 130 | -------------------------------------------------------------------------------- /sptunnel/sptunnelimpl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __sptunnelimpl_hpp__ 7 | #define __sptunnelimpl_hpp__ 8 | 9 | #include "spthread.hpp" 10 | 11 | #include "spmsgdecoder.hpp" 12 | #include "sphandler.hpp" 13 | #include "spresponse.hpp" 14 | 15 | class SP_TunnelArg { 16 | public: 17 | static SP_TunnelArg * create(); 18 | 19 | enum { eCreate, eNormal, eDestroy }; 20 | 21 | void setTunnelStatus( int status ); 22 | int getTunnelStatus(); 23 | 24 | void setTunnelSid( SP_Sid_t sid ); 25 | SP_Sid_t getTunnelSid(); 26 | 27 | void setBackendStatus( int status ); 28 | int getBackendStatus(); 29 | 30 | void setBackendSid( SP_Sid_t sid ); 31 | SP_Sid_t getBackendSid(); 32 | 33 | void addRef(); 34 | void release(); 35 | 36 | private: 37 | sp_thread_mutex_t mMutex; 38 | unsigned char mRefCount; 39 | 40 | unsigned char mTunnelStatus, mBackendStatus; 41 | SP_Sid_t mTunnelSid, mBackendSid; 42 | 43 | SP_TunnelArg(); 44 | ~SP_TunnelArg(); 45 | }; 46 | 47 | class SP_TunnelDecoder : public SP_MsgDecoder { 48 | public: 49 | SP_TunnelDecoder(); 50 | virtual ~SP_TunnelDecoder(); 51 | 52 | virtual int decode( SP_Buffer * inBuffer ); 53 | 54 | SP_Buffer * getBuffer(); 55 | 56 | SP_Buffer * takeBuffer(); 57 | 58 | private: 59 | SP_Buffer * mBuffer; 60 | }; 61 | 62 | class SP_BackendHandler : public SP_Handler { 63 | public: 64 | SP_BackendHandler( SP_TunnelArg * tunnelArg ); 65 | virtual ~SP_BackendHandler(); 66 | 67 | // return -1 : terminate session, 0 : continue 68 | virtual int start( SP_Request * request, SP_Response * response ); 69 | 70 | // return -1 : terminate session, 0 : continue 71 | virtual int handle( SP_Request * request, SP_Response * response ); 72 | 73 | virtual void error( SP_Response * response ); 74 | 75 | virtual void timeout( SP_Response * response ); 76 | 77 | virtual void close(); 78 | 79 | private: 80 | SP_TunnelArg * mArg; 81 | }; 82 | 83 | #ifdef WIN32 84 | typedef class SP_IocpDispatcher SP_MyDispatcher; 85 | #else 86 | typedef class SP_Dispatcher SP_MyDispatcher; 87 | #endif 88 | 89 | class SP_MsgBlockList; 90 | 91 | class SP_TunnelHandler : public SP_Handler { 92 | public: 93 | SP_TunnelHandler( SP_MyDispatcher * dispatcher, 94 | const char * dstHost, int dstPort ); 95 | 96 | virtual ~SP_TunnelHandler(); 97 | 98 | // return -1 : terminate session, 0 : continue 99 | virtual int start( SP_Request * request, SP_Response * response ); 100 | 101 | // return -1 : terminate session, 0 : continue 102 | virtual int handle( SP_Request * request, SP_Response * response ); 103 | 104 | virtual void error( SP_Response * response ); 105 | 106 | virtual void timeout( SP_Response * response ); 107 | 108 | virtual void close(); 109 | 110 | private: 111 | SP_MyDispatcher * mDispatcher; 112 | SP_TunnelArg * mArg; 113 | 114 | SP_MsgBlockList * mMsgBlockList; 115 | 116 | char mHost[ 32 ]; 117 | int mPort; 118 | }; 119 | 120 | #endif 121 | 122 | -------------------------------------------------------------------------------- /win32/README: -------------------------------------------------------------------------------- 1 | spserver/win32 README 2 | 3 | spserver/win32 is a TCP server framework library written in C++ based on IOCP. 4 | 5 | SP_IocpServer implements the Half-Sync/Half-Async pattern. It uses a single 6 | thread to process IO (the async layer), and a thread pool to process the service 7 | logic (the sync layer, the long time duration work can be done here). 8 | 9 | SP_IocpLFServer implements the Leader/Follower pattern. 10 | 11 | SP_IocpDispatcher designs to apply a half-async/half-sync thread pool for both 12 | server and client sockets. 13 | 14 | 15 | 16 | You can get the code from the spserver home page: 17 | 18 | http://code.google.com/p/spserver/ 19 | 20 | Any and all comments are appreciated. 21 | 22 | Enjoy! 23 | 24 | -- stephen liu 25 | 26 | -------------------------------------------------------------------------------- /win32/spgnutls/spgnutls.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="spgnutls" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=spgnutls - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "spgnutls.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "spgnutls.mak" CFG="spgnutls - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "spgnutls - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "spgnutls - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "spgnutls - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\gnutls\include" /I "..\..\spserver" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 45 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 46 | # ADD RSC /l 0x804 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LIB32=link.exe -lib 51 | # ADD BASE LIB32 /nologo 52 | # ADD LIB32 /nologo 53 | 54 | !ELSEIF "$(CFG)" == "spgnutls - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\gnutls\include" /I "..\..\spserver" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 69 | # ADD RSC /l 0x804 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LIB32=link.exe -lib 74 | # ADD BASE LIB32 /nologo 75 | # ADD LIB32 /nologo 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "spgnutls - Win32 Release" 82 | # Name "spgnutls - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\..\gnutls\spgnutls.cpp 89 | # End Source File 90 | # End Group 91 | # Begin Group "Header Files" 92 | 93 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 94 | # Begin Source File 95 | 96 | SOURCE=..\..\gnutls\spgnutls.hpp 97 | # End Source File 98 | # End Group 99 | # End Target 100 | # End Project 101 | -------------------------------------------------------------------------------- /win32/spmatrixssl/spmatrixssl.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="spmatrixssl" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=spmatrixssl - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "spmatrixssl.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "spmatrixssl.mak" CFG="spmatrixssl - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "spmatrixssl - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "spmatrixssl - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "spmatrixssl - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\matrixssl" /I "..\..\spserver" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 45 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 46 | # ADD RSC /l 0x804 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LIB32=link.exe -lib 51 | # ADD BASE LIB32 /nologo 52 | # ADD LIB32 /nologo 53 | 54 | !ELSEIF "$(CFG)" == "spmatrixssl - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\matrixssl" /I "..\..\spserver" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 69 | # ADD RSC /l 0x804 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LIB32=link.exe -lib 74 | # ADD BASE LIB32 /nologo 75 | # ADD LIB32 /nologo 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "spmatrixssl - Win32 Release" 82 | # Name "spmatrixssl - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\..\matrixssl\spmatrixssl.cpp 89 | # End Source File 90 | # Begin Source File 91 | 92 | SOURCE=..\..\matrixssl\sslSocket.c 93 | # End Source File 94 | # End Group 95 | # Begin Group "Header Files" 96 | 97 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 98 | # Begin Source File 99 | 100 | SOURCE=..\..\matrixssl\spmatrixssl.hpp 101 | # End Source File 102 | # Begin Source File 103 | 104 | SOURCE=..\..\matrixssl\sslSocket.h 105 | # End Source File 106 | # End Group 107 | # End Target 108 | # End Project 109 | -------------------------------------------------------------------------------- /win32/spopenssl/spopenssl.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="spopenssl" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=spopenssl - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "spopenssl.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "spopenssl.mak" CFG="spopenssl - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "spopenssl - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "spopenssl - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "spopenssl - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\openssl\include" /I "..\..\spserver" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 45 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 46 | # ADD RSC /l 0x804 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LIB32=link.exe -lib 51 | # ADD BASE LIB32 /nologo 52 | # ADD LIB32 /nologo 53 | 54 | !ELSEIF "$(CFG)" == "spopenssl - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\openssl\include" /I "..\..\spserver" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 69 | # ADD RSC /l 0x804 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LIB32=link.exe -lib 74 | # ADD BASE LIB32 /nologo 75 | # ADD LIB32 /nologo 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "spopenssl - Win32 Release" 82 | # Name "spopenssl - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\..\openssl\spopenssl.cpp 89 | # End Source File 90 | # End Group 91 | # Begin Group "Header Files" 92 | 93 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 94 | # Begin Source File 95 | 96 | SOURCE=..\..\openssl\spopenssl.hpp 97 | # End Source File 98 | # End Group 99 | # End Target 100 | # End Project 101 | -------------------------------------------------------------------------------- /win32/spserver.dsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spsoft/spserver/c2c887ff7b8354d0051f62aac286ea79bdaa07c8/win32/spserver.dsw -------------------------------------------------------------------------------- /win32/spxyssl/spxyssl.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="spxyssl" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=spxyssl - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "spxyssl.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "spxyssl.mak" CFG="spxyssl - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "spxyssl - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "spxyssl - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "spxyssl - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\xyssl-0.9\include" /I "..\..\spserver" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 45 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 46 | # ADD RSC /l 0x804 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LIB32=link.exe -lib 51 | # ADD BASE LIB32 /nologo 52 | # ADD LIB32 /nologo 53 | 54 | !ELSEIF "$(CFG)" == "spxyssl - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\xyssl-0.9\include" /I "..\..\spserver" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 69 | # ADD RSC /l 0x804 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LIB32=link.exe -lib 74 | # ADD BASE LIB32 /nologo 75 | # ADD LIB32 /nologo 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "spxyssl - Win32 Release" 82 | # Name "spxyssl - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\..\xyssl\spxyssl.cpp 89 | # End Source File 90 | # End Group 91 | # Begin Group "Header Files" 92 | 93 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 94 | # Begin Source File 95 | 96 | SOURCE=..\..\xyssl\spxyssl.hpp 97 | # End Source File 98 | # End Group 99 | # End Target 100 | # End Project 101 | -------------------------------------------------------------------------------- /win32/testiocpchat/testiocpchat.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="testiocpchat" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=testiocpchat - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "testiocpchat.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "testiocpchat.mak" CFG="testiocpchat - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "testiocpchat - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "testiocpchat - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "testiocpchat - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 47 | # ADD RSC /l 0x804 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 spserver.lib ws2_32.lib MSVCRTD.LIB /nologo /subsystem:console /machine:I386 /libpath:"..\Release" 54 | 55 | !ELSEIF "$(CFG)" == "testiocpchat - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "Debug" 60 | # PROP BASE Intermediate_Dir "Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "Debug" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 71 | # ADD RSC /l 0x804 /d "_DEBUG" 72 | # SUBTRACT RSC /x 73 | BSC32=bscmake.exe 74 | # ADD BASE BSC32 /nologo 75 | # ADD BSC32 /nologo 76 | LINK32=link.exe 77 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | # ADD LINK32 spserver.lib ws2_32.lib MSVCRTD.LIB /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmt.lib" /nodefaultlib:"msvcrt.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /pdbtype:sept /libpath:"..\Debug" 79 | # SUBTRACT LINK32 /map /nodefaultlib /force 80 | 81 | !ENDIF 82 | 83 | # Begin Target 84 | 85 | # Name "testiocpchat - Win32 Release" 86 | # Name "testiocpchat - Win32 Debug" 87 | # Begin Group "Source Files" 88 | 89 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 90 | # Begin Source File 91 | 92 | SOURCE=..\..\spserver\testiocpchat.cpp 93 | # End Source File 94 | # End Group 95 | # Begin Group "Header Files" 96 | 97 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 98 | # End Group 99 | # Begin Group "Resource Files" 100 | 101 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 102 | # End Group 103 | # End Target 104 | # End Project 105 | -------------------------------------------------------------------------------- /win32/testiocphttp/testiocphttp.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="testiocphttp" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=testiocphttp - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "testiocphttp.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "testiocphttp.mak" CFG="testiocphttp - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "testiocphttp - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "testiocphttp - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "testiocphttp - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 47 | # ADD RSC /l 0x804 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 spserver.lib ws2_32.lib MSVCRTD.LIB /nologo /subsystem:console /machine:I386 /libpath:"..\Release" 54 | 55 | !ELSEIF "$(CFG)" == "testiocphttp - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "Debug" 60 | # PROP BASE Intermediate_Dir "Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "Debug" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 71 | # ADD RSC /l 0x804 /d "_DEBUG" 72 | # SUBTRACT RSC /x 73 | BSC32=bscmake.exe 74 | # ADD BASE BSC32 /nologo 75 | # ADD BSC32 /nologo 76 | LINK32=link.exe 77 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | # ADD LINK32 spserver.lib ws2_32.lib MSVCRTD.LIB /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmt.lib" /nodefaultlib:"msvcrt.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /pdbtype:sept /libpath:"..\Debug" 79 | # SUBTRACT LINK32 /map /nodefaultlib /force 80 | 81 | !ENDIF 82 | 83 | # Begin Target 84 | 85 | # Name "testiocphttp - Win32 Release" 86 | # Name "testiocphttp - Win32 Debug" 87 | # Begin Group "Source Files" 88 | 89 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 90 | # Begin Source File 91 | 92 | SOURCE=..\..\spserver\testiocphttp.cpp 93 | # End Source File 94 | # End Group 95 | # Begin Group "Header Files" 96 | 97 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 98 | # End Group 99 | # Begin Group "Resource Files" 100 | 101 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 102 | # End Group 103 | # End Target 104 | # End Project 105 | -------------------------------------------------------------------------------- /win32/testthreadpool/testthreadpool.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="testthreadpool" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=testthreadpool - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "testthreadpool.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "testthreadpool.mak" CFG="testthreadpool - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "testthreadpool - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "testthreadpool - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "testthreadpool - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x804 /d "NDEBUG" 47 | # ADD RSC /l 0x804 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 spserver.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\Release" 54 | 55 | !ELSEIF "$(CFG)" == "testthreadpool - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "Debug" 60 | # PROP BASE Intermediate_Dir "Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "Debug" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x804 /d "_DEBUG" 71 | # ADD RSC /l 0x804 /d "_DEBUG" 72 | # SUBTRACT RSC /x 73 | BSC32=bscmake.exe 74 | # ADD BASE BSC32 /nologo 75 | # ADD BSC32 /nologo 76 | LINK32=link.exe 77 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | # ADD LINK32 spserver.lib ws2_32.lib MSVCRTD.LIB /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcmt.lib" /nodefaultlib:"msvcrt.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /pdbtype:sept /libpath:"..\Debug" 79 | # SUBTRACT LINK32 /map /nodefaultlib /force 80 | 81 | !ENDIF 82 | 83 | # Begin Target 84 | 85 | # Name "testthreadpool - Win32 Release" 86 | # Name "testthreadpool - Win32 Debug" 87 | # Begin Group "Source Files" 88 | 89 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 90 | # Begin Source File 91 | 92 | SOURCE=..\..\spserver\testthreadpool.cpp 93 | # End Source File 94 | # End Group 95 | # Begin Group "Header Files" 96 | 97 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 98 | # End Group 99 | # Begin Group "Resource Files" 100 | 101 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 102 | # End Group 103 | # End Target 104 | # End Project 105 | -------------------------------------------------------------------------------- /xyssl/Makefile: -------------------------------------------------------------------------------- 1 | 2 | #-------------------------------------------------------------------- 3 | 4 | CC = gcc 5 | AR = ar cru 6 | CFLAGS = -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC 7 | SOFLAGS = -shared 8 | LDFLAGS = -lstdc++ -lpthread -lresolv 9 | 10 | LINKER = $(CC) 11 | LINT = lint -c 12 | RM = /bin/rm -f 13 | 14 | XYSSL_INCL = -I$(HOME)/xyssl-0.9/include 15 | XYSSL_LIB = -L$(HOME)/xyssl-0.9/library -lxyssl 16 | 17 | LIBEVENT_LIB = -L$(HOME)/libevent -levent 18 | 19 | SPSERVER_INCL = -I../spserver 20 | SPSERVER_LIB = -L../spserver -lspserver 21 | 22 | CFLAGS += $(XYSSL_INCL) $(SPSERVER_INCL) 23 | LDFLAGS += $(LIBEVENT_LIB) $(XYSSL_LIB) $(SPSERVER_LIB) 24 | 25 | #-------------------------------------------------------------------- 26 | 27 | LIBOBJS = spxyssl.o 28 | 29 | TARGET = libspxyssl.so \ 30 | testechos 31 | 32 | #-------------------------------------------------------------------- 33 | 34 | all: $(TARGET) 35 | 36 | libspxyssl.so: $(LIBOBJS) 37 | $(LINKER) $(SOFLAGS) $^ -o $@ 38 | 39 | testechos: testechos.o 40 | $(LINKER) -L. -lspxyssl $(LDFLAGS) $^ -o $@ 41 | 42 | clean: 43 | @( $(RM) *.o vgcore.* core core.* $(TARGET) ) 44 | 45 | #-------------------------------------------------------------------- 46 | 47 | # make rule 48 | %.o : %.c 49 | $(CC) $(CFLAGS) -c $^ -o $@ 50 | 51 | %.o : %.cpp 52 | $(CC) $(CFLAGS) -c $^ -o $@ 53 | 54 | -------------------------------------------------------------------------------- /xyssl/README: -------------------------------------------------------------------------------- 1 | spserver/xyssl README 2 | 3 | 1.Introduction 4 | 5 | spserver/xyssl is a plugin for spserver, it enables spserver to support ssl. 6 | 7 | 2.Building 8 | 9 | Before building spserver/xyssl, XYSSL must been installed. Test with XYSSL 0.9. 10 | 11 | You can donwload XYSSL from its home page: 12 | 13 | http://xyssl.org/ 14 | 15 | Edit spserver/xyssl/Makefile to specify the path of XYSSL: 16 | 17 | XYSSL_INCL = -I 18 | XYSSL_LIB = -L -lxyssl 19 | 20 | To build libspxyssl.so, type 21 | 22 | $ cd spserver/xyssl 23 | $ make 24 | 25 | This will build all the targets include examples. You can run the 26 | example programs: 27 | 28 | bash-2.05a$ ./testechos 29 | testechos[28745]: Listen on port [1995] 30 | 31 | You can use the stelnet to visit: 32 | 33 | ./stelnet 127.0.0.1 1995 34 | 35 | 36 | Enjoy! 37 | 38 | -- stephen liu 39 | 40 | -------------------------------------------------------------------------------- /xyssl/demo.crt: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 2 (0x2) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=NO, ST=TEST, L=TEST, O=TEST, OU=TEST, CN=TEST/Email=TEST@TEST.COM 7 | Validity 8 | Not Before: Dec 18 02:06:26 2000 GMT 9 | Not After : Dec 18 02:06:26 2001 GMT 10 | Subject: C=NO, ST=TEST, L=TEST, O=TEST, OU=DEMO, CN=DEMO/Email=TEST@TEST.COM 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (512 bit) 14 | Modulus (512 bit): 15 | 00:c8:46:d3:a7:b5:da:58:b1:5a:08:6b:28:a8:7b: 16 | a5:9b:4a:83:1e:58:4f:0b:18:9e:aa:83:11:27:97: 17 | 24:92:70:0b:47:f4:c8:74:a1:58:92:19:35:88:b3: 18 | 8a:b4:ae:ee:e2:98:5d:bf:d4:53:b8:c6:0c:a1:da: 19 | be:b6:b2:18:f9 20 | Exponent: 65537 (0x10001) 21 | X509v3 extensions: 22 | X509v3 Basic Constraints: 23 | CA:FALSE 24 | Netscape Comment: 25 | OpenSSL Generated Certificate 26 | X509v3 Subject Key Identifier: 27 | 64:2B:31:23:69:F6:49:10:96:EB:BB:5E:91:F2:12:54:37:E6:B3:6B 28 | X509v3 Authority Key Identifier: 29 | keyid:BA:E8:35:48:75:8B:37:A9:77:48:D5:7A:B3:AB:34:C2:41:7C:FF:0E 30 | DirName:/C=NO/ST=TEST/L=TEST/O=TEST/OU=TEST/CN=TEST/Email=TEST@TEST.COM 31 | serial:00 32 | 33 | Signature Algorithm: md5WithRSAEncryption 34 | c0:36:98:cd:32:2d:65:59:60:a9:c9:ca:fa:ba:d8:d6:b1:89: 35 | 16:8b:ae:a5:6f:ea:c3:a0:b1:55:27:0b:04:42:a2:2f:33:39: 36 | fc:46:79:5d:63:33:bf:a7:b2:32:01:a7:17:13:6b:c6:67:2b: 37 | ee:ee:37:3e:64:e4:bb:5d:e9:28:5b:1b:46:33:3d:c1:27:fb: 38 | 8c:ff:ef:e5:49:22:18:e7:6a:03:4c:80:67:45:41:7c:48:e2: 39 | a8:a4:d4:7e:18:09:1d:2d:ab:bd:f0:97:ac:ba:5a:28:46:51: 40 | a0:d3:80:b2:83:70:d4:9a:a6:d0:5f:46:77:43:0e:aa:25:d3: 41 | 19:3c 42 | test haha 43 | -----BEGIN CERTIFICATE----- 44 | MIIDHTCCAoagAwIBAgIBAjANBgkqhkiG9w0BAQQFADB2MQswCQYDVQQGEwJOTzEN 45 | MAsGA1UECBMEVEVTVDENMAsGA1UEBxMEVEVTVDENMAsGA1UEChMEVEVTVDENMAsG 46 | A1UECxMEVEVTVDENMAsGA1UEAxMEVEVTVDEcMBoGCSqGSIb3DQEJARYNVEVTVEBU 47 | RVNULkNPTTAeFw0wMDEyMTgwMjA2MjZaFw0wMTEyMTgwMjA2MjZaMHYxCzAJBgNV 48 | BAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNUMQ0wCwYDVQQKEwRU 49 | RVNUMQ0wCwYDVQQLEwRERU1PMQ0wCwYDVQQDEwRERU1PMRwwGgYJKoZIhvcNAQkB 50 | Fg1URVNUQFRFU1QuQ09NMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMhG06e12lix 51 | WghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHShWJIZNYizirSu7uKYXb/UU7jG 52 | DKHavrayGPkCAwEAAaOB/jCB+zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P 53 | cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUZCsxI2n2SRCW 54 | 67tekfISVDfms2swgaAGA1UdIwSBmDCBlYAUuug1SHWLN6l3SNV6s6s0wkF8/w6h 55 | eqR4MHYxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIEwRURVNUMQ0wCwYDVQQHEwRURVNU 56 | MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMQ0wCwYDVQQDEwRURVNUMRww 57 | GgYJKoZIhvcNAQkBFg1URVNUQFRFU1QuQ09NggEAMA0GCSqGSIb3DQEBBAUAA4GB 58 | AMA2mM0yLWVZYKnJyvq62NaxiRaLrqVv6sOgsVUnCwRCoi8zOfxGeV1jM7+nsjIB 59 | pxcTa8ZnK+7uNz5k5Ltd6ShbG0YzPcEn+4z/7+VJIhjnagNMgGdFQXxI4qik1H4Y 60 | CR0tq73wl6y6WihGUaDTgLKDcNSaptBfRndDDqol0xk8 61 | -----END CERTIFICATE----- 62 | -------------------------------------------------------------------------------- /xyssl/demo.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIBOgIBAAJBAMhG06e12lixWghrKKh7pZtKgx5YTwsYnqqDESeXJJJwC0f0yHSh 3 | WJIZNYizirSu7uKYXb/UU7jGDKHavrayGPkCAwEAAQJAMXKzTWQr/dwEA7IZfsfQ 4 | kq/qAbMCCRZSDn1/3cuGfxT0Vd/gIXLP+yXdEC1jW1LJoBIhWQLnZHEwyKAS6OIz 5 | 0QIhAP4U3GC+SHfJ27PSGv+hjXp47QNbvvmL5T+SXqqHjqgVAiEAycn2FtiNmkzW 6 | ttLkfdZL609c49d+ac0OiTkMfBTbolUCIA9HZ901dBwn+ls85jy7FUvpG6+ZA8nz 7 | 3KxO+/xbPHvlAiB78tJ2tg5E+W3qXyB7K2b244jrazL7SjnjkGda0HUZAQIhAJVp 8 | ms+n0W3jGqEqUntQFbAfjnUo5FIZCjbiz4glt3Do 9 | -----END RSA PRIVATE KEY----- 10 | -------------------------------------------------------------------------------- /xyssl/spxyssl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #ifndef __spxyssl_hpp__ 7 | #define __spxyssl_hpp__ 8 | 9 | #include "spiochannel.hpp" 10 | 11 | class SP_XysslChannel : public SP_IOChannel { 12 | public: 13 | SP_XysslChannel( void * cert, void * key ); 14 | virtual ~SP_XysslChannel(); 15 | 16 | virtual int init( int fd ); 17 | 18 | virtual int receive( SP_Session * session ); 19 | 20 | private: 21 | virtual int write_vec( struct iovec * vector, int count ); 22 | 23 | int mFd; 24 | 25 | void * mCtx, * mSession; 26 | void * mCert, * mKey; 27 | 28 | static int xrly_ciphers[]; 29 | }; 30 | 31 | class SP_XysslChannelFactory : public SP_IOChannelFactory { 32 | public: 33 | SP_XysslChannelFactory(); 34 | virtual ~SP_XysslChannelFactory(); 35 | 36 | virtual SP_IOChannel * create() const; 37 | 38 | int init( const char * certFile, const char * keyFile ); 39 | 40 | private: 41 | void * mCert; 42 | void * mKey; 43 | }; 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /xyssl/testechos.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Stephen Liu 3 | * For license terms, see the file COPYING along with this library. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "spmsgdecoder.hpp" 14 | #include "spbuffer.hpp" 15 | 16 | #include "spserver.hpp" 17 | #include "sphandler.hpp" 18 | #include "spresponse.hpp" 19 | #include "sprequest.hpp" 20 | #include "sputils.hpp" 21 | 22 | #include "spxyssl.hpp" 23 | 24 | class SP_EchoHandler : public SP_Handler { 25 | public: 26 | SP_EchoHandler(){} 27 | virtual ~SP_EchoHandler(){} 28 | 29 | // return -1 : terminate session, 0 : continue 30 | virtual int start( SP_Request * request, SP_Response * response ) { 31 | request->setMsgDecoder( new SP_MultiLineMsgDecoder() ); 32 | response->getReply()->getMsg()->append( 33 | "Welcome to line echo server, enter 'quit' to quit.\r\n" ); 34 | 35 | return 0; 36 | } 37 | 38 | // return -1 : terminate session, 0 : continue 39 | virtual int handle( SP_Request * request, SP_Response * response ) { 40 | SP_MultiLineMsgDecoder * decoder = (SP_MultiLineMsgDecoder*)request->getMsgDecoder(); 41 | SP_CircleQueue * queue = decoder->getQueue(); 42 | 43 | int ret = 0; 44 | for( ; NULL != queue->top(); ) { 45 | char * line = (char*)queue->pop(); 46 | 47 | if( 0 != strcasecmp( line, "quit" ) ) { 48 | response->getReply()->getMsg()->append( line ); 49 | response->getReply()->getMsg()->append( "\r\n" ); 50 | } else { 51 | response->getReply()->getMsg()->append( "Byebye\r\n" ); 52 | ret = -1; 53 | } 54 | 55 | free( line ); 56 | } 57 | 58 | return ret; 59 | } 60 | 61 | virtual void error( SP_Response * response ) {} 62 | 63 | virtual void timeout( SP_Response * response ) {} 64 | 65 | virtual void close() {} 66 | }; 67 | 68 | class SP_EchoHandlerFactory : public SP_HandlerFactory { 69 | public: 70 | SP_EchoHandlerFactory() {} 71 | virtual ~SP_EchoHandlerFactory() {} 72 | 73 | virtual SP_Handler * create() const { 74 | return new SP_EchoHandler(); 75 | } 76 | }; 77 | 78 | //--------------------------------------------------------- 79 | 80 | int main( int argc, char * argv[] ) 81 | { 82 | #ifdef LOG_PERROR 83 | openlog( "testechos", LOG_CONS | LOG_PID | LOG_PERROR, LOG_USER ); 84 | #else 85 | openlog( "testechos", LOG_CONS | LOG_PID, LOG_USER ); 86 | #endif 87 | 88 | int port = 1995; 89 | 90 | SP_Server server( "", port, new SP_EchoHandlerFactory() ); 91 | 92 | SP_XysslChannelFactory * sslFactory = new SP_XysslChannelFactory(); 93 | sslFactory->init( "demo.crt", "demo.key" ); 94 | server.setIOChannelFactory( sslFactory ); 95 | 96 | server.runForever(); 97 | 98 | return 0; 99 | } 100 | 101 | --------------------------------------------------------------------------------