Beispiel #1
0
boost::tuple<boost::tribool, const char *> request_parser::parse(
	http_request &request, const char *begin, const char *end)
{
	while (begin != end) {
		const char *line_end;
		if (*begin == '\n' && m_line.size() > 0 && m_line[m_line.size() - 1] == '\r') {
			line_end = begin;
		} else {
			line_end = find_crlf(begin, end);
		}
		m_line.append(begin, line_end);

		if (line_end == end)
			return boost::make_tuple(boost::tribool(boost::indeterminate), end);

		begin = line_end + 1;

		auto result = parse_line(request, m_line);
		if (result || !result)
			return boost::make_tuple(result, begin);

		m_line.resize(0);
	}

	return boost::make_tuple(boost::tribool(boost::indeterminate), end);
}
Beispiel #2
0
/**
 * handle_receive: splits incomming lines from irc at \r\n and
 * sends them to process_incomming_data. Incomplete lines is stored and
 * merged in buffer over several recv's if necessary. 
 * @param watcher
 * @param events_flags
 */
void Client::handle_receive(ev::io &watcher, int events_flags) {
    char recv_buffer[MAX_BUFFER_SIZE];
    int size = recv(socketFd, &recv_buffer, MAX_BUFFER_SIZE, 0);

    if (size > 0) {
        if (buffer_size + size > MAX_BUFFER_SIZE) {
            std::cout << "Error: buffer overflow" << std::endl;
            buffer_size = 0;
            return;
        }

        memcpy(buffer + buffer_size, recv_buffer, size);
        size = buffer_size + size;
        buffer[size] = '\0';

        int offset;
        while ((offset = find_crlf(buffer, size)) > 1) {
            buffer[offset - 2] = '\0';
            std::string line = buffer;
            process_incomming_data(line);
            memmove(buffer, buffer + offset, size - offset);
            size = size - offset;
        }
    }

    buffer_size = size;
}
Beispiel #3
0
/** Constroi e atribui o header HTTP ao 'buf' (respeitando 'bufsize').
 *
 *  A mensagem e construida de acordo com os parametros.
 *  @todo Remover valores arbitrarios dos buffers.
 *  @return O numero de caracteres efetivamente atribuidos a 'buf' ou
 *          -1 em erro.
 */
int http_build_header(struct c_handler* h)
{
  int n;

  //~ char last_modif[BUFFER_SIZE];
  //LIDAR COM O TEMPO!!!!!!
  //strftime (timebuf)

  n = snprintf(h->answer_header, h->answer_header_size,
                                          "%s %d %s\r\n"
                                          "Server: %s\r\n"
                                          "Content-Type: %s\r\n"
                                          "Content-Length: %d\r\n"
                                          //~ "Last-Modified: %s"
                                          "Connection: close\r\n"
                                          "\r\n",
                                          PROTOCOL, h->filestatus, h->filestatusmsg,
                                          PACKAGE_NAME,
                                          h->filetype,
                                          h->filesize);
  if (!find_crlf(h->answer_header))
    return -1;

  return n;
}
Beispiel #4
0
static void parse_request_header(struct http_request *r, char *src, int max_len)
{
    int i = 0;
    char *curr_line = NULL;
    int curr_line_len = 0;
    int content_length = 0;
    while(i < max_len) {
        curr_line = &src[i];
        curr_line_len = find_crlf(curr_line, max_len-i);
        if(curr_line_len < 0) {
            i = -1;
            break;
        }
        if(curr_line_len == 0) {
            i += 2;
            break;
        }
        if(curr_line_len > 16 && (!strncmp(curr_line, "Content-Length: ", 16))) {
            int cls_len = curr_line_len-16;
            char *cls = alloca(cls_len+1);
            cls[cls_len] = '\0';
            memcpy(cls, &curr_line[16], cls_len);
            content_length = atoi(cls);
        }
        i += curr_line_len+2;
    }
    if(i <= 0 || i > max_len) {
        r->length = -1;
    } else  {
        r->header_length = i;
        r->length = i + content_length;
    }
}
Beispiel #5
0
void serf_util_readline(
    const char **data,
    apr_size_t *len,
    int acceptable,
    int *found)
{
    const char *start;
    const char *cr;
    const char *lf;
    int want_cr;
    int want_crlf;
    int want_lf;

    /* If _only_ CRLF is acceptable, then the scanning needs a loop to
     * skip false hits on CR characters. Use a separate function.
     */
    if (acceptable == SERF_NEWLINE_CRLF) {
        find_crlf(data, len, found);
        return;
    }

    start = *data;
    cr = lf = NULL;
    want_cr = acceptable & SERF_NEWLINE_CR;
    want_crlf = acceptable & SERF_NEWLINE_CRLF;
    want_lf = acceptable & SERF_NEWLINE_LF;

    if (want_cr || want_crlf) {
        cr = memchr(start, '\r', *len);
    }
    if (want_lf) {
        lf = memchr(start, '\n', *len);
    }

    if (cr != NULL) {
        if (lf != NULL) {
            if (cr + 1 == lf)
                *found = want_crlf ? SERF_NEWLINE_CRLF : SERF_NEWLINE_CR;
            else if (want_cr && cr < lf)
                *found = SERF_NEWLINE_CR;
            else
                *found = SERF_NEWLINE_LF;
        }
        else if (cr == start + *len - 1) {
            /* the CR occurred in the last byte of the buffer. this could be
             * a CRLF split across the data boundary.
             * ### FIX THIS LOGIC? does caller need to detect?
             */
            *found = want_crlf ? SERF_NEWLINE_CRLF_SPLIT : SERF_NEWLINE_CR;
        }
        else if (want_cr)
            *found = SERF_NEWLINE_CR;
        else /* want_crlf */
            *found = SERF_NEWLINE_NONE;
    }
    else if (lf != NULL)
        *found = SERF_NEWLINE_LF;
    else
        *found = SERF_NEWLINE_NONE;

    switch (*found) {
      case SERF_NEWLINE_LF:
        *data = lf + 1;
        break;
      case SERF_NEWLINE_CR:
      case SERF_NEWLINE_CRLF:
      case SERF_NEWLINE_CRLF_SPLIT:
        *data = cr + 1 + (*found == SERF_NEWLINE_CRLF);
        break;
      case SERF_NEWLINE_NONE:
        *data += *len;
        break;
      default:
        /* Not reachable */
        return;
    }

    *len -= *data - start;
}
Beispiel #6
0
/*
 * Function: pop_getline
 *
 * Purpose: Get a line of text from the connection and return a
 * 	pointer to it.  The carriage return and linefeed at the end of
 * 	the line are stripped, but periods at the beginnings of lines
 * 	are NOT dealt with in any special way.
 *
 * Arguments:
 * 	server	The server from which to get the line of text.
 *
 * Returns: The number of characters in the line, which is returned in
 * 	LINE, not including the final null.  A return value of 0
 * 	indicates a blank line.  A negative return value indicates an
 * 	error (in which case the contents of LINE are undefined.  In
 * 	case of error, an error message is copied into pop_error.
 *
 * Notes: The line returned is overwritten with each call to pop_getline.
 *
 * Side effects: Closes the connection on error.
 *
 * THE RETURNED LINE MAY CONTAIN EMBEDDED NULLS!
 */
static int
pop_getline (popserver server, char **line)
{
#define GETLINE_ERROR "Error reading from server: "

  int ret;
  int search_offset = 0;

  if (server->data)
    {
      char *cp = find_crlf (server->buffer + server->buffer_index,
			    server->data);
      if (cp)
	{
	  int found;
	  int data_used;

	  found = server->buffer_index;
	  data_used = (cp + 2) - server->buffer - found;

	  *cp = '\0';		/* terminate the string to be returned */
	  server->data -= data_used;
	  server->buffer_index += data_used;

	  if (pop_debug)
	    /* Embedded nulls will truncate this output prematurely,
	       but that's OK because it's just for debugging anyway. */
	    fprintf (stderr, "<<< %s\n", server->buffer + found);
	  *line = server->buffer + found;
	  return (data_used - 2);
	}
      else
	{
	  memmove (server->buffer, server->buffer + server->buffer_index,
		   server->data);
	  /* Record the fact that we've searched the data already in
             the buffer for a CRLF, so that when we search below, we
             don't have to search the same data twice.  There's a "-
             1" here to account for the fact that the last character
             of the data we have may be the CR of a CRLF pair, of
             which we haven't read the second half yet, so we may have
             to search it again when we read more data. */
	  search_offset = server->data - 1;
	  server->buffer_index = 0;
	}
    }
  else
    {
      server->buffer_index = 0;
    }

  while (1)
    {
      /* There's a "- 1" here to leave room for the null that we put
         at the end of the read data below.  We put the null there so
         that find_crlf knows where to stop when we call it. */
      if (server->data == server->buffer_size - 1)
	{
	  server->buffer_size += GETLINE_INCR;
	  server->buffer = (char *)realloc (server->buffer, server->buffer_size);
	  if (! server->buffer)
	    {
	      strcpy (pop_error, "Out of memory in pop_getline");
	      pop_trash (server);
	      return (-1);
	    }
	}
      ret = RECV (server->file, server->buffer + server->data,
		  server->buffer_size - server->data - 1, 0);
      if (ret < 0)
	{
	  snprintf (pop_error, ERROR_MAX, "%s%s",
		    GETLINE_ERROR, strerror (errno));
	  pop_trash (server);
	  return (-1);
	}
      else if (ret == 0)
	{
	  strcpy (pop_error, "Unexpected EOF from server in pop_getline");
	  pop_trash (server);
	  return (-1);
	}
      else
	{
	  char *cp;
	  server->data += ret;
	  server->buffer[server->data] = '\0';

	  cp = find_crlf (server->buffer + search_offset,
			  server->data - search_offset);
	  if (cp)
	    {
	      int data_used = (cp + 2) - server->buffer;
	      *cp = '\0';
	      server->data -= data_used;
	      server->buffer_index = data_used;

	      if (pop_debug)
		fprintf (stderr, "<<< %s\n", server->buffer);
	      *line = server->buffer;
	      return (data_used - 2);
	    }
	  /* As above, the "- 1" here is to account for the fact that
	     we may have read a CR without its accompanying LF. */
	  search_offset += ret - 1;
	}
    }

  /* NOTREACHED */
}
Beispiel #7
0
void ICACHE_FLASH_ATTR web_fini(const uint8 * fname)
{
	struct buf_fini *p = (struct buf_fini *) os_zalloc(sizeof(struct buf_fini));
	if(p == NULL) {
#if DEBUGSOO > 1
		os_printf("Error mem!\n");
#endif
		return;
	}
	TCP_SERV_CONN * ts_conn = &p->ts_conn;
	WEB_SRV_CONN * web_conn = &p->web_conn;
	web_conn->bffiles[0] = WEBFS_INVALID_HANDLE;
	web_conn->bffiles[1] = WEBFS_INVALID_HANDLE;
	web_conn->bffiles[2] = WEBFS_INVALID_HANDLE;
	web_conn->bffiles[3] = WEBFS_INVALID_HANDLE;
	ts_conn->linkd = (uint8 *)web_conn;
	ts_conn->sizeo = FINI_BUF_SIZE;
	ts_conn->pbufo = p->buf;
	rom_strcpy(ts_conn->pbufo, (void *)fname, MAX_FILE_NAME_SIZE);
#if DEBUGSOO > 1
	os_printf("Run ini file: %s\n", ts_conn->pbufo);
#endif
	if(!web_inc_fopen(ts_conn, ts_conn->pbufo)) {
#if DEBUGSOO > 1
		os_printf("file not found!\n");
#endif
		return;
	}
	if(fatCache.flags & WEBFS_FLAG_ISZIPPED) {
#if DEBUGSOO > 1
		os_printf("\nError: file is ZIPped!\n");
#endif
		web_inc_fclose(web_conn);
		return;
	}
	user_uart_wait_tx_fifo_empty(1,1000);
	while(1) {
		web_conn->msgbufsize = ts_conn->sizeo;
		web_conn->msgbuflen = 0;
		uint8 *pstr = web_conn->msgbuf = ts_conn->pbufo;
		if(CheckSCB(SCB_RETRYCB)) { // повторный callback? да
#if DEBUGSOO > 2
			os_printf("rcb ");
#endif
			if(web_conn->func_web_cb != NULL) web_conn->func_web_cb(ts_conn);
			if(CheckSCB(SCB_RETRYCB)) break; // повторить ещё раз? да.
		}
		uint16 len = WEBFSGetArray(web_conn->webfile, pstr, FINI_BUF_SIZE);
#if DEBUGSOO > 3
		os_printf("ReadF[%u]=%u\n", web_conn->webfile, len);
#endif
		if(len) { // есть байты в файле
			pstr[len] = '\0';
			int sslen = 0;
			while(pstr[sslen] == '\n' || pstr[sslen] == '\r') sslen++;
			if(sslen == 0) {
				int nslen = find_crlf(pstr, len);
				if(nslen != 0) {
					pstr[nslen] = '\0'; // закрыть string calback-а
					while((nslen < len) && (pstr[nslen] == '\n' || pstr[nslen] == '\r')) nslen++;
#if DEBUGSOO > 3
					os_printf("String:%s\n", pstr);
#endif

					if(!os_memcmp((void*)pstr, "inc:", 4)) { // "inc:file_name"
						if(!web_inc_fopen(ts_conn, &pstr[4])) {
#if DEBUGSOO > 1
							os_printf("file not found!");
#endif
						};
					}
					else web_int_callback(ts_conn);
				};
				sslen = nslen;
			};
			// откат файла
			WEBFSStubs[web_conn->webfile].addr -= len;
			WEBFSStubs[web_conn->webfile].bytesRem += len;
			// передвинуть указатель в файле на считанные байты с учетом маркера, без добавки длины для передачи
			WEBFSStubs[web_conn->webfile].addr += sslen;
			WEBFSStubs[web_conn->webfile].bytesRem -= sslen;
		}
		else if(web_inc_fclose(web_conn)) {
			if(web_conn->web_disc_cb != NULL) web_conn->web_disc_cb(web_conn->web_disc_par);
			return;
		}
	}
}