~ubuntu-branches/ubuntu/saucy/resiprocate/saucy-proposed

« back to all changes in this revision

Viewing changes to resip/recon/MOHParkServer/HttpBase.cxx

  • Committer: Package Import Robot
  • Author(s): Daniel Pocock
  • Date: 2012-05-17 19:29:59 UTC
  • Revision ID: package-import@ubuntu.com-20120517192959-vv00m77isztdy64q
Tags: upstream-1.8.2
ImportĀ upstreamĀ versionĀ 1.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef HAVE_CONFIG_H
 
2
#include "config.h"
 
3
#endif
 
4
 
 
5
#include <cassert>
 
6
 
 
7
#include <rutil/Data.hxx>
 
8
#include <rutil/Socket.hxx>
 
9
#include <resip/stack/Symbols.hxx>
 
10
#include <rutil/TransportType.hxx>
 
11
#include <rutil/Logger.hxx>
 
12
#include <resip/stack/Tuple.hxx>
 
13
#include <rutil/DnsUtil.hxx>
 
14
#include <rutil/ParseBuffer.hxx>
 
15
#include <resip/stack/Transport.hxx>
 
16
 
 
17
#include "AppSubsystem.hxx"
 
18
#include "HttpBase.hxx"
 
19
#include "HttpConnection.hxx"
 
20
#include "WebAdmin.hxx"
 
21
#include "rutil/WinLeakCheck.hxx"
 
22
 
 
23
 
 
24
using namespace resip;
 
25
using namespace mohparkserver;
 
26
using namespace std;
 
27
 
 
28
#define RESIPROCATE_SUBSYSTEM AppSubsystem::MOHPARKSERVER
 
29
 
 
30
 
 
31
HttpBase::~HttpBase()
 
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
 
 
49
HttpBase::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
 
 
131
void 
 
132
HttpBase::buildFdSet(FdSet& fdset)
 
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
 
 
146
void 
 
147
HttpBase::process(FdSet& fdset)
 
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
      }
 
171
      makeSocketNonBlocking(sock);
 
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
 
 
200
void 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
 
 
214
bool HttpBase::isSane()
 
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
 */