Exemple #1
0
int ReadHeaderHeader()
{
    BEGIN("ReadHeaderHeader");
    int input;

    if ((input = mgetv(GBSC_LENGTH)) != GBSC)
    {
        if (seof()==0)
        {
            WHEREAMI();
            printf("Illegal GOB Start Code. Read: %d\n",input);
        }
        return(-1);
    }
    return(0);
}
Exemple #2
0
void process_http(connection *co)
{
	char *data = data = co->buffer.data;
	int pos, read;
	
	if (co->buffer.length == 0 || co->http.ready == 1 || co->http.error == 1) {
		return;
	}
	
	/* 0 will be erased by the next read()'ing loop */
	data[co->buffer.length] = '\0';
	
	data = &data[co->http.pos];
	
	if (*data == '\0') {
		return;
	}
	
	switch(co->http.step) {
		case 0:
			pos = seof(data);
			if (pos == -1) {
				return;
			}
			
			if (strncasecmp(data, "POST ", 5) == 0) {
				co->http.type = HTTP_POST;
			} else if (strncasecmp(data, "GET ", 4) == 0) {
				co->http.type = HTTP_GET;
			} else {
				/* Other methods are not implemented yet */
				co->http.error = 1;
				
				return;
			}
			co->http.pos = pos;
			co->http.step = 1;
			
			process_http(co);
			break;
		case 1:
			pos = seof(data);
			if (pos == -1) {

				return;
			}
			if (pos == 1 || (pos == 2 && *data == '\r')) {
				

				if (co->http.type == HTTP_GET) {
					/* Ok, at this point we have a blank line. Ready for GET */
					co->http.ready = 1;
					co->buffer.data[co->http.pos] = '\0';

					return;
				} else {
					/* Content-Length is mandatory in case of POST */
					if (co->http.contentlength == 0) {
						co->http.error = 1;
						
						return;
					} else {
						co->http.step = 2;
					}
				}
			} else if (co->http.type == HTTP_POST) {
				/* looking for content-length instruction */
				if (pos <= 25 && strncasecmp("content-length: ", data, 16) == 0) {
					int cl = atoi(&data[16]);
					
					/* Content-length can't be negative... */
					if (cl < 1 || cl > MAX_CONTENT_LENGTH) {
						co->http.error = 1;
						return;
					}
					/* At this time we are ready to read "cl" bytes contents */
					co->http.contentlength = cl;
					
				}
			}
			co->http.pos += pos;
			process_http(co);
			break;
		case 2:
			read = strlen(data);
			co->http.pos += read;
			co->http.read += read;

			if (co->http.read >= co->http.contentlength) {
				co->http.ready = 1;
				
				/* no more than content-length */
				co->buffer.data[co->http.pos - (co->http.read - co->http.contentlength)] = '\0';
			}
			break;
		default:
			break;
	}
}
Exemple #3
0
/* Just a lightweight http request processor */
void process_http(ape_socket *co, acetables *g_ape)
{
	ape_buffer *buffer = &co->buffer_in;
	http_state *http = co->parser.data;
	ape_parser *parser = &co->parser;
	
	char *data = buffer->data;
	int pos, read, p = 0;
	
	if (buffer->length == 0 || parser->ready == 1 || http->error == 1) {
		return;
	}

	/* 0 will be erased by the next read()'ing loop */
	data[buffer->length] = '\0';
	
	data = &data[http->pos];
	
	if (*data == '\0') {
		return;
	}
	
	/* Update the address of http->data and http->uri if buffer->data has changed (realloc) */
	if (http->buffer_addr != NULL && buffer->data != http->buffer_addr) {
		if (http->data != NULL) http->data = &buffer->data[(void *)http->data - (void *)http->buffer_addr];
		if (http->uri != NULL) http->uri = &buffer->data[(void *)http->uri - (void *)http->buffer_addr];
		http->buffer_addr = buffer->data;
	}
	
	switch(http->step) {
		case 0:
			pos = seof(data, '\n');
			if (pos == -1) {
				return;
			}
			
			switch(*(unsigned int *)data) {
#ifdef _LITTLE_ENDIAN
				case 0x20544547: /* GET + space */
#endif
#ifdef _BIG_ENDIAN
				case 0x47455420: /* GET + space */
#endif
					http->type = HTTP_GET;
					p = 4;
					break;
#ifdef _LITTLE_ENDIAN
				case 0x54534F50: /* POST */
#endif
#ifdef _BIG_ENDIAN
				case 0x504F5354: /* POST */
#endif
					http->type = HTTP_POST;
					p = 5;
					break;
				default:
					ape_log(APE_INFO, __FILE__, __LINE__, g_ape, "Invalid HTTP method in request: %s", data);
					http->error = 1;
					shutdown(co->fd, 2);
					return;
			}
			
			if (data[p] != '/') {
				http->error = 1;
				shutdown(co->fd, 2);
				return;
			} else {
				int i = p;
				while (p++) {
					switch(data[p]) {
						case ' ':
							http->pos = pos;
							http->step = 1;
							http->uri = &data[i];
							http->buffer_addr = buffer->data;
							data[p] = '\0';
							process_http(co, g_ape);
							return;
						case '?':
							if (data[p+1] != ' ' && data[p+1] != '\r' && data[p+1] != '\n') {
								http->buffer_addr = buffer->data;
								http->data = &data[p+1];
							}
							break;
						case '\r':
						case '\n':
						case '\0':
							ape_log(APE_INFO, __FILE__, __LINE__, g_ape, "Invalid line ending in request: %s", data);
							http->error = 1;
							shutdown(co->fd, 2);
							return;
					}
				}
			}
			break;
		case 1:
			pos = seof(data, '\n');
			if (pos == -1) {

				return;
			}
			if (pos == 1 || (pos == 2 && *data == '\r')) {
				if (http->type == HTTP_GET) {
					/* Ok, at this point we have a blank line. Ready for GET */
					buffer->data[http->pos] = '\0';
					urldecode(http->uri);
					parser->onready(parser, g_ape);
					parser->ready = -1;
					buffer->length = 0;
					return;
				} else if (http->type == HTTP_GET_WS) { /* WebSockets handshake needs to read 8 bytes */
					//urldecode(http->uri);
					http->contentlength = 8;
					http->buffer_addr = buffer->data;
					http->data = &buffer->data[http->pos+(pos)];
					http->step = 2;
				} else {
					/* Content-Length is mandatory in case of POST */
					if (http->contentlength == 0) {
						http->error = 1;
						shutdown(co->fd, 2);
						return;
					} else {
						http->buffer_addr = buffer->data; // save the addr
						http->data = &buffer->data[http->pos+(pos)];
						http->step = 2;
					}
				}
			} else {
				struct _http_header_line *hl;

				if ((hl = parse_header_line(data)) != NULL) {
					hl->next = http->hlines;
					http->hlines = hl;
					if (strcasecmp(hl->key.val, "host") == 0) {
						http->host = hl->value.val;
					}
				}
				if (http->type == HTTP_POST) {
					/* looking for content-length instruction */
					if (pos <= 25 && strncasecmp("content-length: ", data, 16) == 0) {
						int cl = atoi(&data[16]);

						/* Content-length can't be negative... */
						if (cl < 1 || cl > MAX_CONTENT_LENGTH) {
							http->error = 1;
							shutdown(co->fd, 2);
							return;
						}
						/* At this time we are ready to read "cl" bytes contents */
						http->contentlength = cl;

					}
				} else if (http->type == HTTP_GET) {
					if (strncasecmp("Sec-WebSocket-Key1: ", data, 20) == 0) {
						http->type = HTTP_GET_WS;
					}
				}
			}
			http->pos += pos;
			process_http(co, g_ape);
			break;
		case 2:
			read = buffer->length - http->pos; // data length
			http->pos += read;
			http->read += read;
			
			if (http->read >= http->contentlength) {

				parser->ready = 1;
				urldecode(http->uri);
				/* no more than content-length */
				buffer->data[http->pos - (http->read - http->contentlength)] = '\0';
				
				parser->onready(parser, g_ape);
				parser->ready = -1;
				buffer->length = 0;
			}
			break;
		default:
			break;
	}
}
Exemple #4
0
static CONN_STATE process( const POLL_MODE pollMode, const char callGrade )
{
   KWBoolean master  = (KWBoolean) ( pollMode == POLL_ACTIVE ?
                                       KWTrue : KWFalse );
   KWBoolean aborted = KWFalse;
   XFER_STATE state =  (XFER_STATE) (master ? XFER_SENDINIT : XFER_RECVINIT);
   XFER_STATE old_state = XFER_EXIT;
                              /* Initialized to any state but the
                                 original value of "state"           */
   XFER_STATE save_state = XFER_EXIT;
   char currentGrade = (char) ((unsigned char) 0xff);

/*--------------------------------------------------------------------*/
/*  Yea old state machine for the high level file transfer procotol   */
/*--------------------------------------------------------------------*/

   while( state != XFER_EXIT )
   {
      printmsg(state == old_state ? 14 : 4 ,
               "process: Machine state is = %c", state );
      old_state = state;

      if ( terminate_processing != aborted )
      {
         aborted = terminate_processing;
         state = XFER_ABORT;
      }

      switch( state )
      {

         case XFER_SENDINIT:  /* Initialize outgoing protocol        */
            state = sinit();
            break;

         case XFER_RECVINIT:  /* Initialize Receive protocol         */
            state = rinit();
            break;

         case XFER_MASTER:    /* Begin master mode                   */
            master = KWTrue;
            state = XFER_NEXTJOB;
            resetGrade( );    /* Reset best grade status             */
            currentGrade = E_firstGrade;
            break;

         case XFER_SLAVE:     /* Begin slave mode                    */
            master = KWFalse;
            state = XFER_RECVHDR;
            break;

         case XFER_NEXTJOB:   /* Look for work in local queue        */
            state = scandir( rmtname, currentGrade );
            break;

         case XFER_REQUEST:   /* Process next file in current job
                                 in queue                            */
            state = newrequest();
            break;

         case XFER_PUTFILE:   /* Got local transmit request          */
            state = ssfile();
            break;

         case XFER_GETFILE:   /* Got local tranmit request           */
            state = srfile();
            break;

         case XFER_SENDDATA:  /* Remote accepted our work, send data */
            state = sdata();
            break;

         case XFER_SENDEOF:   /* File xfer complete, send EOF        */
            state = seof( master );
            break;

         case XFER_FILEDONE:  /* Receive or transmit is complete     */
            state = (XFER_STATE) (master ? XFER_REQUEST : XFER_RECVHDR);
            break;

         case XFER_NEXTGRADE: /* Process next grade of local files   */
            currentGrade = nextGrade( callGrade );

            if ( currentGrade )
               state = XFER_NEXTJOB;
            else
               state = XFER_NOLOCAL;
            break;

         case XFER_NOLOCAL:   /* No local work, remote have any?     */
            state = sbreak();
            break;

         case XFER_NOREMOTE:  /* No remote work, local have any?     */
            state = schkdir( (KWBoolean) (pollMode == POLL_ACTIVE ?
                                             KWTrue : KWFalse ),
                              callGrade );
            break;

         case XFER_RECVHDR:   /* Receive header from other host      */
            state = rheader();
            break;

         case XFER_TAKEFILE:  /* Set up to receive remote requested
                                 file transfer                       */
            state = rrfile();
            break;

         case XFER_GIVEFILE:  /* Set up to transmit remote
                                 requuest file transfer              */
            state = rsfile();
            break;

         case XFER_RECVDATA:  /* Receive file data from other host   */
            state = rdata();
            break;

         case XFER_RECVEOF:
            state = reof();
            break;

         case XFER_LOST:      /* Lost the other host, flame out      */
            printmsg(0,"process: Connection lost to %s, "
                       "previous system state = %c",
                       rmtname, save_state );
            hostp->status.hstatus = HS_CALL_FAILED;
            state = XFER_EXIT;
            break;

         case XFER_ABORT:     /* Internal error, flame out           */
            printmsg(0,"process: Aborting connection to %s, "
                       "previous system state = %c",
                       rmtname, save_state );
            hostp->status.hstatus = HS_CALL_FAILED;
            state = XFER_ENDP;
            break;

         case XFER_ENDP:      /* Terminate the protocol              */
            state = endp();
            break;

         default:
            printmsg(0,"process: Unknown state = %c, "
                       "previous system state = %c",
                       state, save_state );
            state = XFER_ABORT;
            break;
      } /* switch */

      save_state = old_state; /* Used only if we abort               */

   } /* while( state != XFER_EXIT ) */

/*--------------------------------------------------------------------*/
/*           Protocol is complete, terminate the connection           */
/*--------------------------------------------------------------------*/

   return CONN_TERMINATE;

} /* process */