reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
HttpBase.cxx
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include "rutil/ResipAssert.h"
6
7#include <rutil/Data.hxx>
8#include <rutil/Socket.hxx>
11#include <rutil/Logger.hxx>
12#include <resip/stack/Tuple.hxx>
13#include <rutil/DnsUtil.hxx>
14#include <rutil/ParseBuffer.hxx>
16
17#include "AppSubsystem.hxx"
18#include "HttpBase.hxx"
19#include "HttpConnection.hxx"
20#include "WebAdmin.hxx"
22
23
24using namespace resip;
25using namespace mohparkserver;
26using namespace std;
27
28#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER
29
30
32{
33#if defined(WIN32)
34 closesocket(mFd);
35#else
36 close(mFd);
37#endif
38 mFd=0;
39 for( int i=0; i<MaxConnections; i++)
40 {
41 if ( mConnection[i] )
42 {
43 delete mConnection[i] ; mConnection[i]=0;
44 }
45 }
46}
47
48
49HttpBase::HttpBase( int port, IpVersion ipVer, const Data& realm ):
50 mRealm(realm),
51 nextConnection(0),
52 mTuple(Data::Empty,port,ipVer,TCP,Data::Empty)
53{
54 sane = true;
55
56 for ( int i=0 ; i<MaxConnections; i++)
57 {
58 mConnection[i]=0;
59 }
60
61#ifdef USE_IPV6
62 mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0);
63#else
64 mFd = ::socket(PF_INET, SOCK_STREAM, 0);
65#endif
66
67 if ( mFd == INVALID_SOCKET )
68 {
69 int e = getErrno();
70 ErrLog (<< "Failed to create socket: " << strerror(e));
71 sane = false;
72 return;
73 }
74
75 DebugLog (<< "Creating fd=" << (int)mFd
76 << (ipVer == V4 ? " V4/" : " V6/") );
77
78 int on = 1;
79#if !defined(WIN32)
80 if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) )
81#else
82 if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) )
83#endif
84 {
85 int e = getErrno();
86 ErrLog (<< "Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e));
87 sane = false;
88 return;
89 }
90
91 DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple));
92
93 if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR )
94 {
95 int e = getErrno();
96 if ( e == EADDRINUSE )
97 {
98 ErrLog (<< mTuple << " already in use ");
99 }
100 else
101 {
102 ErrLog (<< "Could not bind to " << mTuple);
103 }
104 sane = false;
105 return;
106 }
107
108 bool ok = makeSocketNonBlocking(mFd);
109 if ( !ok )
110 {
111 ErrLog (<< "Could not make HTTP socket non-blocking " << port );
112 sane = false;
113 return;
114 }
115
116 // do the listen, seting the maximum queue size for compeletly established
117 // sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete
118 // queue size(see man listen)
119 int e = listen(mFd,5 );
120
121 if (e != 0 )
122 {
123 int e = getErrno();
124 InfoLog (<< "Failed listen " << strerror(e));
125 sane = false;
126 return;
127 }
128}
129
130
131void
133{
134 fdset.setRead( mFd );
135
136 for( int i=0; i<MaxConnections; i++)
137 {
138 if ( mConnection[i] )
139 {
140 mConnection[i]->buildFdSet(fdset);
141 }
142 }
143}
144
145
146void
148{
149 if (fdset.readyToRead(mFd))
150 {
151 Tuple tuple(mTuple);
152 struct sockaddr& peer = tuple.getMutableSockaddr();
153 socklen_t peerLen = tuple.length();
154 Socket sock = accept( mFd, &peer, &peerLen);
155 if ( sock == SOCKET_ERROR )
156 {
157 int e = getErrno();
158 switch (e)
159 {
160 case EWOULDBLOCK:
161 // !jf! this can not be ready in some cases
162 return;
163 default:
164 ErrLog(<< "Some error reading from socket: " << e);
165 // .bwc. This is almost certainly a bad assert that a nefarious
166 // endpoint could hit.
167 // assert(0); // Transport::error(e);
168 }
169 return;
170 }
172
173 int c = nextConnection;
174 nextConnection = ( nextConnection+1 ) % MaxConnections;
175
176 if ( mConnection[c] )
177 {
178 delete mConnection[c]; mConnection[c] = 0;
179 }
180
181 mConnection[c] = new HttpConnection(*this,sock);
182
183 DebugLog (<< "Received TCP connection as connection=" << c << " fd=" << (int)sock);
184 }
185
186 for( int i=0; i<MaxConnections; i++)
187 {
188 if ( mConnection[i] )
189 {
190 bool ok = mConnection[i]->process(fdset);
191 if ( !ok )
192 {
193 delete mConnection[i]; mConnection[i]=0;
194 }
195 }
196 }
197}
198
199
200void HttpBase::setPage( const Data& page, int pageNumber, int response, const Mime& type )
201{
202 for ( int i=0 ; i<MaxConnections; i++)
203 {
204 if ( mConnection[i] )
205 {
206 if ( mConnection[i]->mPageNumber == pageNumber )
207 {
208 mConnection[i]->setPage( page,response,type );
209 }
210 }
211 }
212}
213
215{
216 return sane;
217}
218
219/* ====================================================================
220 * The Vovida Software License, Version 1.0
221 *
222 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
223 *
224 * Redistribution and use in source and binary forms, with or without
225 * modification, are permitted provided that the following conditions
226 * are met:
227 *
228 * 1. Redistributions of source code must retain the above copyright
229 * notice, this list of conditions and the following disclaimer.
230 *
231 * 2. Redistributions in binary form must reproduce the above copyright
232 * notice, this list of conditions and the following disclaimer in
233 * the documentation and/or other materials provided with the
234 * distribution.
235 *
236 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
237 * and "Vovida Open Communication Application Library (VOCAL)" must
238 * not be used to endorse or promote products derived from this
239 * software without prior written permission. For written
240 * permission, please contact vocal@vovida.org.
241 *
242 * 4. Products derived from this software may not be called "VOCAL", nor
243 * may "VOCAL" appear in their name, without prior written
244 * permission of Vovida Networks, Inc.
245 *
246 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
247 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
248 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
249 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
250 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
251 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
252 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
253 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
254 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
255 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
257 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
258 * DAMAGE.
259 *
260 * ====================================================================
261 *
262 * This software consists of voluntary contributions made by Vovida
263 * Networks, Inc. and many individuals on behalf of Vovida Networks,
264 * Inc. For more information on Vovida Networks, Inc., please see
265 * <http://www.vovida.org/>.
266 *
267 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
Handles cross-platform sockets compatibility.
#define INVALID_SOCKET
Definition Socket.hxx:95
#define SOCKET_ERROR
Definition Socket.hxx:96
static int getErrno()
int Socket
void setPage(const resip::Data &page, int pageNumber, int response=200, const resip::Mime &pType=resip::Mime("text","html"))
Definition HttpBase.cxx:200
HttpBase(int port, resip::IpVersion version, const resip::Data &realm)
Definition HttpBase.cxx:49
void buildFdSet(resip::FdSet &fdset)
Definition HttpBase.cxx:132
friend class HttpConnection
Definition HttpBase.hxx:16
void process(resip::FdSet &fdset)
Definition HttpBase.cxx:147
bool process(resip::FdSet &fdset)
void buildFdSet(resip::FdSet &fdset)
void setPage(const resip::Data &page, int response, const resip::Mime &pType)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
Object-oriented wrapper for your platform's file-descriptor set.
Definition Socket.hxx:162
bool readyToRead(Socket fd)
Definition Socket.hxx:189
void setRead(Socket fd)
Definition Socket.hxx:204
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
Represents a network address.
Definition Tuple.hxx:59
sockaddr & getMutableSockaddr()
Retrieve the binary representation of the socket address for this tuple.
Definition Tuple.hxx:113
socklen_t length() const
Definition Tuple.cxx:655
static Data inet_ntop(const Tuple &tuple)
Converts the binary socket address to presentation format, via the DnsUtil::inet_ntop() method.
Definition Tuple.cxx:939
dcm! – add UnusedChecking(_enum) below;
IpVersion
An enumeration of IP versions.
bool makeSocketNonBlocking(Socket fd)
Definition Socket.cxx:21