Ejemplo n.º 1
0
static _mqx_int httpd_readch(HTTPD_SESSION_STRUCT *session, char *ch) {
    int res;
    
    HTTPD_ASSERT(session && ch);
    HTTPD_ASSERT(session->recv_used >= 0 && session->recv_used < HTTPDCFG_RECV_BUF_LEN);

    if (session->recv_used == 0) {
        HTTPD_DEBUG(5, "recv BEGIN\n");
        res = recv(session->sock, session->recv_buf, HTTPDCFG_RECV_BUF_LEN, 0);
        HTTPD_DEBUG(5, "recv END\n");

        if (res <= 0) {
            *ch = 0;
            return res;
        }
        
        session->recv_used = res;
        session->recv_buf[session->recv_used] = 0;
        session->recv_rd = session->recv_buf;
    }

    *ch = *session->recv_rd++;
    session->recv_used--;

    return 1;
}
Ejemplo n.º 2
0
static void httpd_session_dynamic_task(pointer init_ptr, pointer creator) {
    HTTPD_SES_TASK_PARAM *param = (HTTPD_SES_TASK_PARAM*)init_ptr;
    HTTPD_SESSION_STRUCT *session;
    
    HTTPD_ASSERT(init_ptr);
    
    HTTPD_DEBUG(1, "session task start\n");
    
    session = httpd_ses_alloc(param->server);
    
    if (session) {
        RTCS_task_resume_creator(creator, RTCS_OK);
        
        HTTPD_DEBUG(1, "session task run...\n");
        
        httpd_ses_init(param->server, session, param->sock);
    
        while (HTTPD_SESSION_VALID == session->valid) {
            httpd_ses_process(param->server, session);
        }
    
        httpd_ses_free(session);
    }
    else {
        RTCS_task_resume_creator(creator, (uint_32) RTCS_ERROR);
    }
    
    HTTPD_FREE(init_ptr);
    
    _lwsem_post(&sem_session_counter);
    
    HTTPD_DEBUG(1, "session task stop\n");
}
Ejemplo n.º 3
0
static uint32 get_json_pointer(struct http_request *req)
{
	uint32 i = 0;
	uint32 first_matched = 0;
	uint8 starter = 0;
	int32 checker_brace = 0;   /* checker of '{' '}'*/
	int32 checker_bracket = 0; /* checker of '['  ']' */
	int32 checker_quote = 0;   /* checked of '"' */

	for (i = 0; i < req->sz; i++) {
		switch (req->buff[i]) {
		case '{':
			checker_brace++;
			if ((0 == first_matched)) {
				req->json_start = i;
				starter = '{';
				first_matched = 1;
			}
			break;
		case '}':
			checker_brace--;
			if (starter == '{')
				req->json_end = i;
			break;
		case '[':
			checker_bracket++;
			if ((0 == first_matched)) {
				req->json_start = i;
				starter = '[';
				first_matched = 1;
			}
			break;
		case ']':
			checker_bracket--;
			if (starter == '[')
				req->json_end = i;
			break;
		case '"':
			checker_quote++;
			break;

		default:
			break;
		}
	}

	if (checker_brace || checker_bracket || (checker_quote%2 != 0) ||
		(0 == req->json_start) || (0 == req->json_end) || (req->json_start > req->json_end)) {
		//printf("brace[%d] bracket[%d] quote[%d] content_length[%lld] hd_sz[%d] sz[%d] json_start[%d] json_end[%d]\n",
			//checker_brace, checker_bracket, checker_quote, req->content_length, req->hd_sz, req->sz, req->json_start, req->json_end);
		return 0;
	}
	HTTPD_DEBUG("content_length[%ld] hd_sz[%d] sz[%d] json_start[%d] json_end[%d]\n",
		req->content_length, req->hd_sz, req->sz, req->json_start, req->json_end);
	return (req->json_end-req->json_start + 1);

}
Ejemplo n.º 4
0
/** Send data to socket.
 * \param s < socket
 * \param buf < pointer to data buffer
 * \param len < data length
 * \return length of sent data
 */
static _mqx_int httpd_send(int s, char *buf, int len) {
    int res;

    HTTPD_DEBUG(4, "httpd_send buf:%p len:%d", buf, len);

#if RTCS_MINIMUM_FOOTPRINT
    // for better performance on small ram devices, split data to teo separate packets
    if (len > 2) {
        res = send(s, buf, len / 2, 0);
        
        if (res != RTCS_ERROR)
            res += send(s, buf + res, len - res, 0);
    }
    else
#endif
        res = send(s, buf, len, 0);

    HTTPD_DEBUG(4, "result:%d\n", res);

    return res;
}
Ejemplo n.º 5
0
_mqx_int httpd_readln(HTTPD_SESSION_STRUCT *session, char *buf, _mqx_int max_len) {
    int used = 0, ret;
    char *dst = buf;
    uint_32 err;

    HTTPD_ASSERT(session && dst);
    
    HTTPD_DEBUG(5, "readln session(%p) buf(%p) max_len(%d)\n", session, buf, max_len);

    while (used < max_len) {
#if HTTPDCFG_POLL_MODE
        ret = httpd_readch(session, dst);
#else
        ret = recv(session->sock, dst, 1, 0);
#endif

        if (ret <= 0) {
            err = RTCS_geterror(session->sock);
            *buf = 0;
            HTTPD_DEBUG(5, "readln used(%d) ret(%d) err(0x%x)\n", used, ret, err);
            return ret;
        }

        dst++;
        used++;

        if (*(dst - 1) == '\n') {
            break;
        }
    }

    *dst = 0;
    
    HTTPD_DEBUG(5, "readln len(%d)\n", used);
    return used;
}
Ejemplo n.º 6
0
void httpd_send404(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_DEBUG(3, "http_send404\n");

    session->response.file = fopen(server->params->page404, "r");
    session->response.len = 0;

    if (session->response.file) {
        httpd_sendfile(server, session);
    }
    else {
        httpd_sendhdr(session, 0, 0);
        httpd_sendstr(session->sock, "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
        httpd_sendstr(session->sock, "<BODY><H1>The request URL was not found!</H1>\n");
        httpd_sendstr(session->sock, "</BODY></HTML>\n");
    }
}
Ejemplo n.º 7
0
void httpd_send403(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    HTTPD_DEBUG(3, "http_send403\n");

    session->response.file = fopen(server->params->page403, "r");
    session->response.len = 0;

    if (session->response.file) {
        httpd_sendfile(server, session);
    }
    else {
        httpd_sendhdr(session, 0, 0);
        httpd_sendstr(session->sock, "<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\n");
        httpd_sendstr(session->sock, "<BODY><H1>Forbidden!</H1>\n");
        httpd_sendstr(session->sock, "</BODY></HTML>\n");
    }
}
Ejemplo n.º 8
0
static int32 re_alloc_buff(struct http_request *req)
{
	int8 *orig = req->buff;

	if (NULL != req->sec_websocket_key)
		req->sec_websocket_key_offset = (int32)(req->sec_websocket_key - req->buff);
	if (NULL != req->origin)
		req->origin_offset = (int32)(req->origin - req->buff);
	if (NULL != req->content_type)
		req->content_type_offset = (int32)(req->content_type - req->buff);
	if (NULL != req->host)
		req->host_offset = (int32)(req->host - req->buff);
	if (NULL != req->path)
		req->path_offset = (int32)(req->path - req->buff);
	if (NULL != req->query)
		req->query_offset = (int32)(req->query - req->buff);

	req->buff_size = req->content_length + MAX_HEADER_LEN + 1;
	req->buff = (int8 *)realloc(req->buff, req->content_length + MAX_HEADER_LEN + 1);
	if (NULL == req->buff)
		return -1;

	if (orig != req->buff)
		HTTPD_DEBUG("\nrealloc buffer size from %d to %ld\n", BUFFSIZ, req->content_length + MAX_HEADER_LEN);

	if (NULL != req->sec_websocket_key)
		req->sec_websocket_key = req->buff + req->sec_websocket_key_offset;
	if (NULL != req->origin)
		req->origin = req->buff + req->origin_offset;
	if (NULL != req->content_type)
		req->content_type = req->buff + req->content_type_offset;
	if (NULL != req->host)
		req->host = req->buff + req->host_offset;
	if (NULL != req->path)
		req->path = req->buff + req->path_offset;
	if (NULL != req->query)
		req->query = req->buff + req->query_offset;
	return 0;
}
Ejemplo n.º 9
0
void httpd_sendhdr(HTTPD_SESSION_STRUCT *session, _mqx_int content_len, _mqx_int mod_time) {
    char tmpBuf[100];

    HTTPD_ASSERT(session);

    if (session->response.hdrsent)
        return;

    sprintf(tmpBuf, "HTTP/1.0 %d %s\n",
            session->response.statuscode,
            get_tbl_string((tbl_str_itm_t*)reason_phrase, session->response.statuscode));
    httpd_sendstr(session->sock, tmpBuf);
    httpd_sendstr(session->sock, session->response.header);

    if (session->keep_alive) {
        httpd_sendstr(session->sock, "Connection: Keep-Alive\n");
    }
    else {
        httpd_sendstr(session->sock, "Connection: close\n");
    }

    sprintf(tmpBuf, "Content-Type: %s\n", get_tbl_string((tbl_str_itm_t*)content_type, session->response.contenttype));
    httpd_sendstr(session->sock, tmpBuf);

    //only non zero length cause to send Content-Length header field
    if (0 < content_len) {
        sprintf(tmpBuf, "Content-Length: %d\n", content_len);
        httpd_sendstr(session->sock, tmpBuf);
    }

    httpd_sendstr(session->sock, "\n");

    session->response.hdrsent = 1;

    HTTPD_DEBUG(4, "httpd_sendhdr\n");
}
Ejemplo n.º 10
0
void httpd_sendfile(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session) {
    char *ext;
    int expand = 0;
    int len;
    char buf[HTTPDCFG_MAX_BYTES_TO_SEND + 1];

    HTTPD_ASSERT(server && session);

    HTTPD_DEBUG(3, "httpd_sendfile(%p) %s\n", session, session->request.path);

    ext = strrchr(session->request.path, 46);
    if (ext) {
        if (0 == strcasecmp(ext, ".htm") || 0 == strcasecmp(ext, ".html")) {
            session->response.contenttype = CONTENT_TYPE_HTML;
            expand = 1;
        }
        else if (0 == strcasecmp(ext, ".gif"))
            session->response.contenttype = CONTENT_TYPE_GIF;
        else if (0 == strcasecmp(ext, ".jpg"))
            session->response.contenttype = CONTENT_TYPE_JPG;
        else if (0 == strcasecmp(ext, ".png"))
            session->response.contenttype = CONTENT_TYPE_PNG;
        else if (0 == strcasecmp(ext, ".css"))
            session->response.contenttype = CONTENT_TYPE_CSS;
        else if (0 == strcasecmp(ext, ".js"))
            session->response.contenttype = CONTENT_TYPE_JS;
        else
            session->response.contenttype = CONTENT_TYPE_OCTETSTREAM;
    }

    if (expand) {
        //if there will be any expansion there's no way how to calculate correct length
        //zero length prevents sending Content-Length header field
        httpd_sendhdr(session, 0, 0);
    } else {
        httpd_sendhdr(session, session->response.file->SIZE, 0);
    }

    if (expand) {
        session->response.data = buf;
        len = read(session->response.file, session->response.data, HTTPDCFG_MAX_BYTES_TO_SEND);

        if (len > 0) {
            buf[len] = 0;
			len = httpd_sendextstr(server, session, session->response.data);
            if (!len) {
                session->state = HTTPD_SES_END_REQ;
            }
            else {
                session->response.len += len;
                fseek(session->response.file, session->response.len, SEEK_SET);
            }
        }
        else
            session->state = HTTPD_SES_END_REQ;
    }
    else {
        session->response.data = buf;
        fseek(session->response.file, session->response.len, SEEK_SET);
        len = read(session->response.file, session->response.data, HTTPDCFG_MAX_BYTES_TO_SEND);
        
        HTTPD_DEBUG(4, "httpd_sendfile READ END %d\n", len);
        
        if (len > 0) {
            buf[len] = 0;

            len = httpd_send(session->sock, session->response.data, len);

            if (len < 0) {
                if (errno != EAGAIN)
                    session->state = HTTPD_SES_END_REQ;
            }
            else {
                session->response.len += len;
            }
        }
        else
            session->state = HTTPD_SES_END_REQ;
    }
    HTTPD_DEBUG(4, "httpd_sendfile END %s \n", session->request.path);
}
Ejemplo n.º 11
0
/** Send extended string to socket.
 * \param s < socket
 * \param str < pointer to string
 * \return length of sent data
 */
static _mqx_int httpd_sendextstr(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session, char *str) {
    char *src;
    int len, res;
    char fname[HTTPDCFG_MAX_SCRIPT_LN + 1];

    HTTPD_ASSERT(server && session && str);

    fname[0] = 0;

    if (!session->response.data)
    {
        session->response.data = str;
    }

    src = session->response.data;

    if (session->response.script_token)
    {
        // script token found
        len = (int)strcspn(src, " ;%<>\r\n\t");

        if (len > 1 && len < HTTPDCFG_MAX_SCRIPT_LN)
        {
            strncpy(fname, src, (unsigned long)len);
            fname[len] = 0;

            // call fn
            HTTPD_DEBUG(2, "script ln: %s\r\n", fname);

            httpd_call_fn(server, session, fname);
        }

        if (src[len] == '%' && src[len + 1] == '>')
        {
            session->response.script_token = 0;
            len += 1;
        }

        len++;

        session->response.data = src + len;
    }
    else
    {
        for (len = 0; *src && len < HTTPDCFG_MAX_BYTES_TO_SEND; src++, len++)
        {
            if (*src == '<' && *(src + 1) == '%')
            {
                session->response.script_token = 1;
                src += 2;

                break;
            }
        }

        res = httpd_send(session->sock, session->response.data, len);

        if (res < 0) {
            session->response.script_token = 0;
            res = errno;

            if (res != EAGAIN)
                len = 0;
        }
        else {
            if (len == res) {
                session->response.data = src;
            }
            else {
                session->response.script_token = 0;
                session->response.data += res;
            }
        }
    }

    return len;
}
Ejemplo n.º 12
0
/** server task - httpd main task which create new task for each new request
 */
static void httpd_server_task(pointer init_ptr, pointer creator) {
    HTTPD_STRUCT *server = (HTTPD_STRUCT*)init_ptr;
    int s;
    unsigned short len;
    struct sockaddr_in sin;
    HTTPD_SES_TASK_PARAM *param;
    _mqx_uint res;
    uint_32 stack;
 
    HTTPD_DEBUG(1, "server task start\n");
      
    res = _lwsem_create(&sem_session_counter, server->params->max_ses);

    if (!server && res != MQX_OK)
        goto ERROR;
        
    RTCS_task_resume_creator(creator, RTCS_OK);
    
    HTTPD_DEBUG(1, "server task run...\n");

    while (server->run) {
        // limit maximal opened sessions
        _lwsem_wait(&sem_session_counter);
        
        // allocate session task parameter structure
        param = _mem_alloc_system(sizeof(HTTPD_SES_TASK_PARAM));
        
        if (param) {
            param->server = server;
            param->sock = accept(server->sock, &sin, &len);
            
            if (0 < param->sock) {
                // accept return corect socket number - no error
                
                // try create task for session
                res = RTCS_task_create("httpd session", server->params->ses_prio, server->params->ses_stack, httpd_session_dynamic_task, param);
                
                if (MQX_OK != res) {
                    // session task creation failed, clean and wait...
                    shutdown(param->sock, FLAG_ABORT_CONNECTION);   // abort opened connection
                    _mem_free(param);
                    _lwsem_post(&sem_session_counter);
                    _time_delay(1);
                }
            }
            else {
                // accept return error, clean and wait, then try again...
                _mem_free(param);
                _lwsem_post(&sem_session_counter);
                _time_delay(1);
            }
        }
        else {
            // allocation failed ?!?!? wait some time
            _time_delay(100);
        }
    }
    
    HTTPD_DEBUG(1, "server task stop\n");
    
ERROR:
    RTCS_task_resume_creator(creator, (uint_32)RTCS_ERROR);
}