Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages   Examples  

/opentcp/http/http_server.c

Go to the documentation of this file.
00001 /*
00002  *Copyright (c) 2000-2002 Viola Systems Ltd.
00003  *All rights reserved.
00004  *
00005  *Redistribution and use in source and binary forms, with or without 
00006  *modification, are permitted provided that the following conditions 
00007  *are met:
00008  *
00009  *1. Redistributions of source code must retain the above copyright 
00010  *notice, this list of conditions and the following disclaimer.
00011  *
00012  *2. Redistributions in binary form must reproduce the above copyright 
00013  *notice, this list of conditions and the following disclaimer in the 
00014  *documentation and/or other materials provided with the distribution.
00015  *
00016  *3. The end-user documentation included with the redistribution, if 
00017  *any, must include the following acknowledgment:
00018  *      "This product includes software developed by Viola 
00019  *      Systems (http://www.violasystems.com/)."
00020  *
00021  *Alternately, this acknowledgment may appear in the software itself, 
00022  *if and wherever such third-party acknowledgments normally appear.
00023  *
00024  *4. The names "OpenTCP" and "Viola Systems" must not be used to 
00025  *endorse or promote products derived from this software without prior 
00026  *written permission. For written permission, please contact 
00027  *opentcp@opentcp.org.
00028  *
00029  *5. Products derived from this software may not be called "OpenTCP", 
00030  *nor may "OpenTCP" appear in their name, without prior written 
00031  *permission of the Viola Systems Ltd.
00032  *
00033  *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 
00034  *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00035  *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00036  *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE 
00037  *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00038  *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00039  *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
00040  *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00041  *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00042  *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00043  *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00044  *====================================================================
00045  *
00046  *OpenTCP is the unified open source TCP/IP stack available on a series 
00047  *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
00048  *
00049  *For more information on how to network-enable your devices, or how to 
00050  *obtain commercial technical support for OpenTCP, please see 
00051  *<http://www.violasystems.com/>.
00052  */
00053  
00067 #include<inet/datatypes.h>
00068 #include<inet/globalvariables.h>
00069 #include<inet/debug.h>
00070 #include<inet/system.h>
00071 #include<inet/tcp_ip.h>
00072 #include<inet/http/http_server.h>
00073 
00074 
00075 UINT8 https_enabled = 0; 
00083 struct http_server_state https[NO_OF_HTTP_SESSIONS];
00084 
00093 INT8 https_init(void)
00094 {
00095         UINT8 i;
00096         INT8 soch;
00097 
00098 
00099         for( i=0; i<NO_OF_HTTP_SESSIONS; i++)
00100         {
00101                 https[i].state = HTTPS_STATE_FREE;
00102                 https[i].ownersocket = 0;
00103                 https[i].fstart = 0;
00104                 https[i].fpoint = 0;
00105                 https[i].flen  = 0;
00106                 https[i].funacked = 0;
00107                 
00108                 soch =  tcp_getsocket(TCP_TYPE_SERVER, TCP_TOS_NORMAL, TCP_DEF_TOUT, https_eventlistener);
00109                 
00110                 if(soch < 0)
00111                 {
00112                         DEBUGOUT("HTTP Server uncapable of getting socket\r\n");
00113                         RESET_SYSTEM();
00114                         /*return(-1);*/
00115                 }
00116                 
00117                 https[i].ownersocket = soch;
00118                 
00119                 kick_WD();
00120                 
00121                 soch = tcp_listen(https[i].ownersocket, HTTPS_SERVERPORT);
00122                 
00123                 if(soch < 0)
00124                 {
00125                         DEBUGOUT("HTTP Server uncapable of setting socket to listening mode\r\n");
00126                         RESET_SYSTEM();
00127                         /*return(-1);*/
00128                 }               
00129                 
00130         
00131         } 
00132         
00133         https_enabled  = 1;
00134         
00135         return(i);      
00136         
00137 }
00138 
00139 
00140 /********************************************************************************
00141 Function:               https_run
00142 
00143 Parameters:             void    
00144                                 
00145 Return val:             void
00146                                 
00147 Date:                   13.10.2002
00148 
00149 Desc:                   This function is main 'thread' of HTTP server program
00150                                 and should be called periodically from main loop.
00151 *********************************************************************************/
00152 
00153 void https_run (void)
00154 {
00155         UINT8 i;
00156         INT16 len;
00157         static UINT8 ses = 0;
00158         
00159         if( https_enabled == 0)
00160                 return;
00161                 
00162         /* Walk thru all sessions untill we found something to send or so       */
00163         
00164         for(i=0; i<NO_OF_HTTP_SESSIONS; i++)
00165         {
00166                 kick_WD();
00167                 
00168                 if(ses >= NO_OF_HTTP_SESSIONS)
00169                         ses = 0;
00170         
00171                 if(https[ses].state != HTTPS_STATE_ACTIVE)
00172                 {
00173                         ses++;
00174                         continue;
00175                 }
00176                 
00177                 if(https[ses].funacked != 0)
00178                 {
00179                         ses++;
00180                         continue;               
00181                 }
00182                 
00183                 if(https[ses].fstart == 0)
00184                 {
00185                         ses++;
00186                         continue;               
00187                 }               
00188                 
00189                 /* End of data? */
00190                 
00191                 if( https[ses].fpoint >= https[ses].flen)
00192                 {
00193                         tcp_close(https[ses].ownersocket);
00194                         tcp_abort(https[ses].ownersocket);
00195                         https_deletesession(ses);
00196                         
00197                         ses++;
00198                         
00199                         return;                 
00200                 
00201                 }
00202                 
00203                 /* More data to send    */
00204                 
00205                 len = https_loadbuffer(ses, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET);
00206                         
00207                 if(len<0)
00208                         return;
00209                         
00210                 len = tcp_send(https[ses].ownersocket, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, len); 
00211                 
00212                 if(len<0)
00213                 {
00214                         tcp_close(https[ses].ownersocket);
00215                         https_deletesession(ses);
00216                         
00217                         ses++;
00218 
00219                         return;                 
00220                 
00221                 }
00222                 
00223                 https[ses].funacked = len;
00224                 
00225                 
00226                 /* Serve another session on next run    */
00227                 
00228                 ses++;
00229                 
00230                 return;         
00231                 
00232         
00233         }       
00234         
00235         
00236 
00237 
00238 }
00239 
00240 /********************************************************************************
00241 Function:               https_eventlistener
00242 
00243 Parameters:             INT8 cbhandle - handle to TCP socket where event is coming from 
00244                                 UINT8 event - type of event
00245                                 UINT32 par1 - parameter the meaning of depends on event
00246                                 UINT32 par2 - parameter the meaning of depends on event
00247                                 
00248 Return val:             INT32 - depends on event but usually (-1) is error of some
00249                                                 kind and positive reply means OK
00250                                 
00251 Date:                   13.10.2002
00252 
00253 Desc:                   This function is given to TCP socket as function pointer to be
00254                                 used by TCP engine to make callbacks to inform about events
00255                                 on TCP e.g. arriving data. 
00256 *********************************************************************************/
00257 
00258 
00259 INT32 https_eventlistener (INT8 cbhandle, UINT8 event, UINT32 par1, UINT32 par2)
00260 {
00261         /* This function is called by TCP stack to inform about events  */
00262         
00263         INT16   i;
00264         INT16   session;
00265                 
00266         if( https_enabled == 0)
00267                 return(-1);
00268         
00269         if(cbhandle < 0)
00270                 return(-1);     
00271                 
00272         /* Search for rigth session     */
00273         
00274         session = https_searchsession(cbhandle);        
00275         
00276         switch( event )
00277         {
00278         
00279                 case TCP_EVENT_CONREQ:
00280                 
00281                         /* Do we have a session for requesting socket?  */
00282                         
00283                         if(session < 0)
00284                                 return(-1);
00285 
00286                         
00287                         /* Try to get new session       */
00288                         
00289                         session = https_bindsession(cbhandle);
00290                         
00291                         if(session < 0)                 /* No resources */
00292                                 return(-1);
00293 
00294                         
00295                         return(1);
00296         
00297                 case TCP_EVENT_ABORT:
00298                 
00299                         if(session < 0)
00300                                 return(1);
00301                         
00302                         https_deletesession((UINT8)session);            
00303                         
00304                         return(1);
00305                 
00306                 case TCP_EVENT_CONNECTED:
00307                 
00308                         if(session < 0)
00309                                 return(-1);
00310                 
00311                         https_activatesession((UINT8)session);
00312                         
00313                         return(1);
00314                         
00315                 case TCP_EVENT_CLOSE:
00316                 
00317                         if(session < 0)
00318                                 return(-1);
00319                         
00320                         https_deletesession((UINT8)session);            
00321                         
00322                         return(1);              
00323                 
00324                         
00325                 case TCP_EVENT_ACK:
00326                 
00327                         if(session < 0)
00328                                 return(-1);
00329                 
00330                         https[session].fpoint += https[session].funacked;
00331                         https[session].funacked = 0;
00332                 
00333                         return(1);
00334                         
00335                 case TCP_EVENT_DATA:
00336                 
00337                         /* Check for GET request        */
00338                         
00339                         if(session < 0)
00340                                 return(-1);
00341                         
00342                         if(https[session].fstart == 0)
00343                         {
00344                                 if(par1 <= 3)
00345                                         return(1);
00346                                 
00347                                 /* Check for GET        */
00348                                 
00349                                 if(RECEIVE_NETWORK_B() != 'G')
00350                                         return(1);
00351                                 if(RECEIVE_NETWORK_B() != 'E')
00352                                         return(1);      
00353                                 if(RECEIVE_NETWORK_B() != 'T')
00354                                         return(1);                      
00355                                         
00356                                 par1 -= 3;
00357                                 
00358                                 /* Search for '/'       */
00359                                 
00360                                 for(i=0; i<par1; i++)
00361                                 {
00362                                         if(RECEIVE_NETWORK_B() == '/')
00363                                         {
00364                                                 i++;
00365                                                 break;
00366                                         }
00367                                 }               
00368                                 
00369                                 par1 -= i;
00370                                 
00371                                 /* Calculate Hash       */
00372                                 
00373                                 i = https_calculatehash(par1);  
00374                                 
00375                                 if(i < 0)
00376                                 {
00377                                         /* Invalid GET  */
00378                                         return(1);
00379                                 }       
00380                                 
00381                                 /* Get FileRef  */
00382                                 
00383                                 i = https_findfile((UINT8)i, (UINT8)session);
00384                                                 
00385                                 
00386                                 return(1);              
00387                                 
00388                         
00389                         }
00390                 
00391                 
00392                         return(1);
00393                 
00394                         
00395                 case TCP_EVENT_REGENERATE:
00396                 
00397                         if(session < 0)
00398                                 return(-1);
00399                 
00400                         if(https[session].state != HTTPS_STATE_ACTIVE)
00401                                 return(-1);
00402                 
00403                         i = https_loadbuffer(session, &net_buf[TCP_APP_OFFSET], (UINT16)par1);
00404                         
00405                         if(i<0)
00406                                 return(-1);
00407                         
00408                         tcp_send(https[session].ownersocket, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i);     
00409                 
00410                         return(i);
00411         
00412         
00413                 default:
00414                         return(-1);
00415         }       
00416 
00417 }
00418 
00419 
00420 void https_deletesession (UINT8 ses)
00421 {
00422         https[ses].state = HTTPS_STATE_FREE;
00423         https[ses].fstart = 0;
00424         https[ses].fpoint = 0;
00425         https[ses].flen  = 0;
00426         https[ses].funacked = 0;
00427 
00428 }
00429 
00430 INT16 https_searchsession (UINT8 soch)
00431 {
00432         UINT8 i;
00433         
00434         for(i=0; i<NO_OF_HTTP_SESSIONS; i++)
00435         {
00436                 if(https[i].ownersocket == soch)
00437                         return(i);
00438                 
00439         }
00440         
00441         return(-1);
00442 
00443 }
00444 
00445 INT16 https_bindsession (UINT8 soch)
00446 {
00447         UINT8 i;
00448         
00449         for(i=0; i<NO_OF_HTTP_SESSIONS; i++)
00450         {
00451                 if(https[i].ownersocket == soch)
00452                 {
00453                         if(https[i].state == HTTPS_STATE_FREE)
00454                         {
00455                                 https[i].state = HTTPS_STATE_RESERVED;
00456                                 return(i);
00457                         }                       
00458                 }       
00459                 
00460         }
00461         
00462         
00463         return(-1);
00464 
00465 }
00466 
00467 void https_activatesession (UINT8 ses)
00468 {
00469         https[ses].state = HTTPS_STATE_ACTIVE;
00470 
00471 }
00472 
00473 INT16 https_calculatehash (UINT32 len)
00474 {
00475         UINT8 hash=0;
00476         UINT8 ch;
00477         UINT8 i;
00478         
00479         
00480         /* Read Max 60 characters */
00481         
00482         if(len > 60)
00483                 len = 60;
00484         
00485         for( i=0; i<len; i++)
00486         {
00487                 ch = RECEIVE_NETWORK_B();
00488                 
00489                 if( ch ==' ')   /* End reached?                 */
00490                         break;
00491                 
00492                 hash *= 37;
00493                 hash += ch;
00494         
00495         }
00496         
00497         if(i==len)
00498                 return(-1);
00499         
00500         /* construct address for Hash table */
00501         
00502         if(hash == 0)           /* User asked defaul file       */
00503         {
00504                 /* Set hash to index.html value */
00505                 
00506                 hash = 0x0B;
00507         
00508         }
00509         
00510         /* Now we have hash value calculated            */
00511         
00512         return( hash );
00513 
00514 }
00515 
00516 

Generated on Sat Jan 25 17:13:14 2003 for OpenTCP by doxygen1.2.18