/* Send one chunk of data of a given size
 */
int httpd_send_chunk(int conn, const char *buf, int len)
{
	int err;

	if (len) {
		/* Send chunk begin header */
		err = httpd_send_chunk_begin(conn, len);
		if (err != WM_SUCCESS)
			return err;
		/* Send our data */
		err = httpd_send(conn, buf, len);
		if (err != WM_SUCCESS)
			return err;
		/* Send chunk end indicator */
		err = httpd_send_crlf(conn);
		if (err != WM_SUCCESS)
			return err;
	} else {
		/* Length is 0, last chunk */
		err = httpd_send(conn, http_last_chunk,
				   sizeof(http_last_chunk) - 1);
		if (err != WM_SUCCESS)
			return err;
	}

	return err;
}
int httpd_send_chunk_begin(int conn, int size)
{

	int err;
	char buf[CHUNK_SIZE_DIGITS];
	int i;
	int digit;
	int begin = 1;

	for (i = CHUNK_SIZE_DIGITS - 1; i >= 0; i--) {
		digit = size & 0xf;
		if (!begin && !size) {
			i++;
			break;
		}
		buf[i] = (digit > 9) ? digit - 0xA + 'a' : digit + '0';
		size = size >> 4;
		begin = 0;
	}
	err = httpd_send(conn, &buf[i], CHUNK_SIZE_DIGITS - i);
	if (err != WM_SUCCESS) {
		return err;
	}

	err = httpd_send_crlf(conn);

	return err;
}
/* Helper function to send an error.
 */
int httpd_send_error(int conn, int http_error)
{
	int err = 0;

	switch (http_error) {
	case HTTP_404:
		err = httpd_send(conn, http_header_404,
				 strlen(http_header_404));
		break;
	case HTTP_500:
		err = httpd_send(conn, http_header_500,
				 strlen(http_header_500));
		break;

	case HTTP_505:
		err = httpd_send(conn, http_header_505,
				 strlen(http_header_505));
		break;
	}

	if (err != WM_SUCCESS) {
		return err;
	}

	err = httpd_send(conn, http_header_type_chunked,
			strlen(http_header_type_chunked));
	if (err != WM_SUCCESS) {
		return err;
	}

	err = httpd_send(conn, http_content_type_plain,
			 sizeof(http_content_type_plain) - 1);
	if (err != WM_SUCCESS) {
		return err;
	}

	err = httpd_send_crlf(conn);
	if (err != WM_SUCCESS) {
		return err;
	}

	err = httpd_send_chunk(conn, httpd_error, strlen(httpd_error));
	if (err != WM_SUCCESS) {
		return err;
	}
	return httpd_send_last_chunk(conn);
}
/* Send the last chunk which is simply an ascii "0\r\n\r\n"
 */
int httpd_send_last_chunk(int conn)
{
	int err;

	err = httpd_send(conn, http_last_chunk,
			    sizeof(http_last_chunk) - 1);

	if (err != WM_SUCCESS) {
		httpd_e("Send last chunk failed");
	}

	return err;
}
static int httpd_send_file(struct fs *fs, int conn,
			   const sys_file_t *sys_file_p)
{
	char data[SND_BUF_LEN];
	int len;
	int total = 0;
	int err = WM_SUCCESS;

	/* Chunk begin */
	err = httpd_send_chunk_begin(conn,
		     htsys_get_file_size(fs, sys_file_p));
	if (err != WM_SUCCESS)
		return err;

	/* Send the file */
	while (TRUE) {
		len = htsys_read(fs, sys_file_p,
				 (unsigned char *)data, SND_BUF_LEN);
		if (len <= 0) {
			if (len < 0)
				httpd_d("read failed\r\n");
			break;
		}
		err = httpd_send(conn, data, len);
		if (err != WM_SUCCESS) {
			httpd_d("Failed to send file (sent %d bytes)\r\n",
				total);
			break;
		}
		total += len;
	}

	htsys_close(fs, sys_file_p);

	if (err != WM_SUCCESS) {
		return err;
	}

	/* Chunk end */
	err = httpd_send_crlf(conn);

	return err;
}
int httpd_send_hdr_from_code(int sock, int stat_code,
			     enum http_content_type content_type)
{
	const char *str;
	unsigned int str_len;
	/*
	 * Set the HTTP Response Status 200 OK, 404 NOT FOUND etc.
	 * Also set the Transfer-Encoding to chunked.
	 */
	switch (stat_code) {
	case -WM_E_HTTPD_HANDLER_404:
		str = http_header_404;
		str_len = strlen(http_header_404);
		break;
	case -WM_E_HTTPD_HANDLER_400:
		str = http_header_400;
		str_len = strlen(http_header_400);
		break;
	case -WM_E_HTTPD_HANDLER_500:
		str = http_header_500;
		str_len = strlen(http_header_500);
		break;
	default:
		/* The handler doesn't want an HTTP error code, but would return
		 * 200 OK with an error in the response */
		str = http_header_200;
		str_len = strlen(http_header_200);
		break;
	}

	if (httpd_send(sock, str, str_len) != WM_SUCCESS) {
		return -WM_FAIL;
	}

	/* Send the Content-Type */
	switch (content_type) {
	case HTTP_CONTENT_JSON:
		str = http_content_type_json_nocache;
		str_len = sizeof(http_content_type_json_nocache) - 1;
		break;
	case HTTP_CONTENT_XML:
		str = http_content_type_xml_nocache;
		str_len = sizeof(http_content_type_xml_nocache) - 1;
		break;
	case HTTP_CONTENT_HTML:
		str = http_content_type_html;
		str_len = sizeof(http_content_type_html) - 1;
		break;
	case HTTP_CONTENT_JPEG:
		str = http_content_type_jpg;
		str_len = sizeof(http_content_type_jpg) - 1;
		break;
	default:
		str = http_content_type_plain;
		str_len = sizeof(http_content_type_plain) - 1;
		break;
	}
	if (httpd_send(sock, str, str_len) != WM_SUCCESS) {
		return -WM_FAIL;
	}
	return WM_SUCCESS;
}
Example #7
0
int http_get(struct httpd * httpd, struct httpctl * ctl)
{
	int (* cgi)(struct tcp_pcb * tp);
	char buf[128];
//	int content_type;
//	int content_len;
//	char * opt;	
	char * ext;	
	struct stat sb;
	int type;
	int hash;
	int size;
	int ret;
	int fd;
	int n;

	strcpy(buf, httpd->root);
	strcat(buf, ctl->uri);

//	for (opt = buf; (*opt); opt++) {
 //		if (*opt == '?') {
//			*opt++ = '\0';
//			break;
//		}
//	}
	
	DBG(DBG_INFO, "path=%s", buf);

	if ((ret = stat(buf, &sb)) < 0) {
		DBG(DBG_ERROR, "404 File Not Found");
		httpd_404(ctl->tp);
		return ret;
	}

	if (S_ISDIR(sb.st_mode)) {
		DBG(DBG_INFO, "is a directory");
		strcat(buf, "/");
		strcat(buf, httpd_page_default);
		if ((ret = stat(buf, &sb)) < 0) {
			strcpy(buf, httpd->root);
			strcat(buf, ctl->uri);	
			return httpd_dirlist(httpd, ctl);
		}
	}

	if (!S_ISREG(sb.st_mode)) {
		DBG(DBG_ERROR, "403 Forbidden");
		httpd_403(ctl->tp);
		return -1;
	}

	if ((fd = open(buf, O_RDONLY)) < 0) {
		DBG(DBG_ERROR, "404 File Not Found");
		httpd_404(ctl->tp);
		return -1;
	}

	ret = 0;

	if ((ext = strrchr(buf, '.')) != NULL) {
		DBG(DBG_INFO, "extension=%s", ext);
		/* skip the '.' */
		ext++;
		hash = mk_ext_hash(ext);

		switch (hash) {
		case EXT_CGI:
			DBG(DBG_INFO, "cgi");
			goto dynamic_cgi;
		case EXT_TXT:
			DBG(DBG_INFO, "text");
			type = text_plain; 
			break;
		case EXT_JPEG:
		case EXT_JPG:
			DBG(DBG_INFO, "jpeg");
			type = image_jpeg; 
			break;
		case EXT_ICO:
			DBG(DBG_INFO, "ico");
		case EXT_GIF:
			DBG(DBG_INFO, "gif");
			type = image_gif; 
			break;
		case EXT_PNG:
			DBG(DBG_INFO, "png");
			type = image_png; 
			break;
		case EXT_JS:
			DBG(DBG_INFO, "js");
			type = application_x_javascript;
			break;
		case EXT_HTML:
		case EXT_HTM:
			DBG(DBG_INFO, "html");
		default:
			type = text_html; 
			break;
		}

		httpd_200(ctl->tp, type);

		while ((n = read(fd, buf, 128)) > 0) {
			if (tcp_send(ctl->tp, buf, n, 0) <= 0) {
				DBG(DBG_ERROR, "tcp_send()");
				ret = -1;
				break;
			}
		}

	} else {
dynamic_cgi:

		size = lseek(fd, 0, SEEK_END);
		DBG(DBG_TRACE, "size=%d", size);

		cgi = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);

		DBG(DBG_TRACE, "cgi=%p", cgi);

		ret = cgi(ctl->tp);
	}

	close(fd);

#if 0
	DBG(DBG_INFO, "file uid=%d", info.fi_uid);

	if (info.fi_uid < __httpd->uid) {
		unsigned int uid;
		
		DBG(DBG_INFO, "info.fi_uid=%d < httpd->uid=%d, auth required", 
			info.fi_uid, __httpd->uid);
		uid = httpd_auth(__http->httpd, __http->usr, __http->pwd);
		if (info.fi_uid < uid) {
			DBG(DBG_ERROR, "401 Unauthorized, uid=%d", uid);
			httpd_401_auth(__tp);
			return -1;
		}
	}

	content_type = __http->ctype;
	content_len = __http->ctlen;

	if (info.fi_mime != _code_) {
		/* detach the PCB */
		tcp_attach(__tp, NULL, __httpd);
		/* release the control structure */
		httpd_free(__httpd, __http);

		httpd_send(__tp, info.fi_mime, (char *)info.fi_data, info.fi_size);
		tcp_close(__tp);
		return 0;
	}

	/* dynamic cgi */
	DBG(DBG_INFO, "dynamic page");
	cgi_call = (httpd_cgi_t)info.fi_data;

	/* reuse the allocated buffer */
	cgi = (struct cgistate *)__http;
	/* XXX: */
	cgi->httpd = __httpd;
	cgi->callback = NULL;

	/* attach the PCB to the CGI handler */
	tcp_attach(__tp, (tcp_callback_t)httpd_cgi_handler, cgi);

	if (cgi_call(__tp, opt, content_type, content_len) < 0) {
		/* close the tcp pcb */
		tcp_close(__tp);
	} else {
		/* if the CGI is still detached, close-it */
		if (cgi->callback == NULL)
			tcp_close(__tp);		
	}
#endif



	return ret;
}
Example #8
0
_mqx_int httpd_sendstr(_mqx_int s, char *str) {
    return httpd_send(s, str, strlen(str));
}
Example #9
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);
}
Example #10
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;
}
int httpd_handle_file(httpd_request_t *req_p, struct fs *fs)
{
	const char *anchor = "/";
	char tmp[HTTPD_MAX_URI_LENGTH+1];
	const char *encoding = NULL;
	char *msg_in, *ptr, *type = NULL;
	int err, msg_in_len = HTTPD_MAX_MESSAGE - 1, conn = req_p->sock;
	int ret;

	msg_in = os_mem_alloc(HTTPD_MAX_MESSAGE + 2);
	if (!msg_in) {
		httpd_e("Failed to allocate memory for file handling");
		/* Check what needs to be returned */
		return -WM_FAIL;
	}
	memset(msg_in, 0, HTTPD_MAX_MESSAGE + 2);

	SYS_FILE_DECL;

	if (!fs) {
		/* The filesystem wasn't mounted properly */
		httpd_send_hdr_from_str(conn, http_header_404,
					CONTENT_TYPE_PLAIN, encoding,
					NO_CACHE_HEADERS, UNUSED_PARAM);
		httpd_send_default_headers(conn,
				req_p->wsgi->hdr_fields);
		httpd_send_crlf(conn);
		httpd_send(conn, FILE_NOT_FOUND, sizeof(FILE_NOT_FOUND));
		ret = WM_SUCCESS;
		goto out;
	}
	struct ftfs_super *f_super = fs_to_ftfs_sb(fs);

	/* Ensure that the anchor is the first part of the filename */
	ptr = strstr(req_p->filename, anchor);
	if (ptr == NULL ||
	    ptr != req_p->filename) {
		httpd_d("No anchor in filename\r\n");
		ret = httpd_send_error(conn, HTTP_500);
		goto out;
	}

	/* Zap the anchor from the filename */
	ptr = req_p->filename + strlen(anchor);
	err = 0;
	/* anchors are only across directory boundaries */
	if (*ptr != '/')
		req_p->filename[err++] = '/';

	while (*ptr && (*ptr != '?')) {
		req_p->filename[err] = *ptr;
		ptr++;
		err++;
	}
	req_p->filename[err] = '\0';

	/* "/" implies a request for index.html */
	if (strncmp(req_p->filename, "/", 2) == 0) {
		strncpy(req_p->filename, http_index_html,
			sizeof(http_index_html));
	}

	/* Find if .gz version exists for file, if it is then serve that */
	type = strrchr(req_p->filename, ISO_period);
	if (type) {
		strncpy(tmp, req_p->filename, sizeof(tmp));
		strncat(tmp, ".gz", 3);
		httpd_d("Look for gz file if it exists: %s\r\n", tmp);
		if (htsys_file_open(fs, tmp, sys_filep) == WM_SUCCESS) {
			/* Gzipped version exists, serve that */
			httpd_d("Serve gzipped file\r\n");
			strncpy(req_p->filename, tmp, HTTPD_MAX_URI_LENGTH + 1);
			encoding = ".gz";
			htsys_close(fs, sys_filep);
		}
	}

	ret = httpd_parse_hdr_tags(req_p, conn, msg_in, msg_in_len);
	if (ret < 0) {
		httpd_d("Parsing headers failed \r\n");
		ret = httpd_send_error(conn, HTTP_500);
		goto out;
	}

	/* It is not a WSGI, check to see if the file exists */
	if (htsys_file_open(fs, req_p->filename, sys_filep) == -WM_FAIL) {
		httpd_w("file not found: %s\r\n", req_p->filename);

		ret = httpd_send_hdr_from_str(conn, http_header_404,
					      type, encoding, NO_CACHE_HEADERS,
					      UNUSED_PARAM);
		httpd_send_default_headers(conn,
				req_p->wsgi->hdr_fields);
		httpd_send_crlf(conn);
		if (ret != WM_SUCCESS)
			goto out;

		ret = htsys_file_open(fs, http_404_html, sys_filep);
		if (ret == WM_SUCCESS) {
			ret = httpd_send_file(fs, conn, sys_filep);
			goto out;
		} else
			httpd_w("No local 404 file.  Sending empty 404"
			      " response.\r\n");
	} else {
		/* Ok, the file exists, is it a script html or just html */
		g_wm_stats.wm_hd_file++;
		if (req_p->if_none_match &&
		    (f_super->fs_crc32 == req_p->etag_val)) {
			/* We do not need the file handle now */
			htsys_close(fs, sys_filep);

			/* Send Not Modified header */

			/* Send header prologue */
			ret = httpd_send(conn, http_header_304_prologue,
					 strlen(http_header_304_prologue));
			if (ret != WM_SUCCESS)
				goto out;
			httpd_send_header(conn, "Server", "Marvell-WM");
			httpd_send_header(conn, "Connection", "Close");

			/* Send ETag */
			int len;
			const char *h = httpd_get_etag_hdr(req_p->etag_val,
							   &len);
			ret = httpd_send(conn, h, len);
			if (ret != WM_SUCCESS)
				goto out;
			/* Close the header */
			ret = httpd_send_crlf(conn);
			goto out;
		} else  {
			ret = httpd_send_hdr_from_str(conn, http_header_200,
						      type, encoding,
						      SEND_CACHE_HEADERS,
						      f_super->fs_crc32);
			httpd_send_default_headers(conn,
					req_p->wsgi->hdr_fields);
			httpd_send_crlf(conn);

			if (ret != WM_SUCCESS)
				goto out;
			ptr = strchr(req_p->filename, ISO_period);
			if (ptr != NULL && strncmp(ptr, http_shtml,
						   sizeof(http_shtml)
						   - 1) == 0) {
				httpd_d("Handling script: %s", req_p->filename);
				ret = handle_script(fs, req_p, conn,
						    sys_filep, msg_in);
				htsys_close(fs, sys_filep);
				if (ret != WM_SUCCESS) {
					httpd_d("Script failed\r\n");
					goto out;
				}
			} else {
				ret = httpd_send_file(fs, conn, sys_filep);
				if (ret != WM_SUCCESS)
					goto out;
			}
		}
	}
	ret = httpd_send_last_chunk(conn);
out:
	os_mem_free(msg_in);
	return ret;
}
/* Send the required HTTP headers on the connection conn
 */
static int httpd_send_hdr_from_str(int conn, const char *statushdr,
				   const char *file_type, const char *encoding,
				   bool send_cache_headers, unsigned etag_val)
{
	int err;

	/* Send the HTTP status header, 200/404, etc.*/
	err = httpd_send(conn, statushdr, strlen(statushdr));
	if (err != WM_SUCCESS) {
		return err;
	}

	/* Set enconding to gz if so */
	if (strncmp(encoding, http_gz, sizeof(http_gz) - 1) == 0) {
		err = httpd_send(conn, http_content_encoding_gz,
				 sizeof(http_content_encoding_gz) - 1);
		if (err != WM_SUCCESS)
			return err;
	}

	if (send_cache_headers &&
	    strncmp(http_shtml, file_type, sizeof(http_shtml) - 1)) {
		err = httpd_send(conn, http_cache_control,
				 sizeof(http_cache_control) - 1);
		if (err != WM_SUCCESS)
			return err;

		int len;
		const char *etag_hdr = httpd_get_etag_hdr(etag_val, &len);
		err = httpd_send(conn, etag_hdr, len);
		if (err != WM_SUCCESS)
			return err;
	}
	if (file_type == NULL) {
		err = httpd_send(conn, http_content_type_binary,
				 sizeof(http_content_type_binary) - 1);
	} else if (strncmp(http_manifest, file_type,
			   sizeof(http_manifest) - 1) == 0) {
		err = httpd_send(conn,
				 http_content_type_text_cache_manifest,
				 sizeof(http_content_type_text_cache_manifest)
				 - 1);
	} else if (strncmp(http_html, file_type,
			   sizeof(http_html) - 1) == 0) {
		err = httpd_send(conn, http_content_type_html,
				 sizeof(http_content_type_html) - 1);
	} else if (strncmp(http_shtml, file_type,
			   sizeof(http_shtml) - 1) == 0) {
		err = httpd_send(conn, http_content_type_html_nocache,
				 sizeof(http_content_type_html_nocache) - 1);
	} else if (strncmp(http_css, file_type,
			   sizeof(http_css) - 1) == 0) {
		err = httpd_send(conn, http_content_type_css,
				 sizeof(http_content_type_css) - 1);
	} else if (strncmp(http_js, file_type,
			   sizeof(http_js) - 1) == 0) {
		err = httpd_send(conn, http_content_type_js,
				 sizeof(http_content_type_js) - 1);
	} else if (strncmp(http_png, file_type,
			   sizeof(http_png) - 1) == 0) {
		err = httpd_send(conn, http_content_type_png,
				 sizeof(http_content_type_png) - 1);
	} else if (strncmp(http_gif, file_type,
			   sizeof(http_gif) - 1) == 0) {
		err = httpd_send(conn, http_content_type_gif,
				 sizeof(http_content_type_gif) - 1);
	} else if (strncmp(http_jpg, file_type,
			   sizeof(http_jpg) - 1) == 0) {
		err = httpd_send(conn, http_content_type_jpg,
				 sizeof(http_content_type_jpg) - 1);
	} else {
		err = httpd_send(conn, http_content_type_plain,
				 sizeof(http_content_type_plain) - 1);
	}

	return err;
}
/* If a script file (shtml), script_file_p is found, send that file to
 * the client over the socket, conn. Process any SSI directives within
 * the file.
 */
static int handle_script(struct fs *fs, httpd_request_t *req, int conn,
		  sys_file_t *script_file_p, char *data_p)
{
	char *cmd, *args;
	int len, err;
	int script_cmd;
	httpd_ssifunction func;
	SYS_FILE_DECL;

	err = WM_SUCCESS;

	/* proccess each line of the script */
	while ((len = htsys_getln(fs, script_file_p, data_p,
				  HTTPD_MAX_MESSAGE + 1)) != 0) {
		if (len < 0) {
			httpd_d("getln failed\r\n");
			err = -WM_FAIL;
			break;
		}

		/* Check if we should start executing a script. */
		script_cmd = httpd_is_script_directive(data_p, len,
						       &cmd, &args);
		if (script_cmd == SSI_INCLUDE_FILE) {
			/* Include another file and send to client */
			if (cmd == NULL)
				continue;

			httpd_d("Opening %s from script", cmd);
			err = htsys_file_open(fs, cmd, sys_filep);
			if (err != WM_SUCCESS) {
				httpd_d("open failed\r\n");
				break;
			}

			httpd_d("sending file %s (%d bytes).\r\n", cmd,
			      htsys_get_file_size(fs, sys_filep));
			err = httpd_send_file(fs, conn, sys_filep);
			if (err != WM_SUCCESS) {
				break;
			}
		} else if (script_cmd == SSI_INCLUDE_VIRTUAL) {
			/* find the function and run it */
			/* it should always at least return a nullfunction */
			if (cmd == NULL)
				continue;
			httpd_d("Invoking SSI %s from script", cmd);
			func = httpd_ssi(cmd);
			/* Pass args in their own buffer so we can use data_p as
			 * scratch */
			if (args == NULL) {
				err = func(req, NULL, conn, data_p);
			} else {
				strncpy(script_args, args, HTTPD_MAX_SSI_ARGS);
				script_args[HTTPD_MAX_SSI_ARGS] = 0;
				err = func(req, script_args, conn, data_p);
			}
		} else {
			/* send embedded html to client */
			err = httpd_send_chunk_begin(conn, len);
			if (err != WM_SUCCESS)
				break;

			err = httpd_send(conn, data_p, len);
			if (err != WM_SUCCESS)
				break;

			err = httpd_send_crlf(conn);
			if (err != WM_SUCCESS)
				break;

		}
	}
	return err;
}
Example #14
0
// HTTP event handler
void tcp_handle_event(chanend tcp_svr, xtcp_connection_t *conn)
{
  // We have received an event from the TCP stack, so respond
  // appropriately

  // Ignore events that are not directly relevant to http
  switch (conn->event)
    {
    case XTCP_IFUP: {
      xtcp_ipconfig_t ipconfig;
      xtcp_get_ipconfig(tcp_svr, &ipconfig);

#if IPV6
      unsigned short a;
      unsigned int i;
      int f;
      xtcp_ipaddr_t *addr = &ipconfig.ipaddr;
      printstr("IPV6 Address = [");
      for(i = 0, f = 0; i < sizeof(xtcp_ipaddr_t); i += 2) {
        a = (addr->u8[i] << 8) + addr->u8[i + 1];
        if(a == 0 && f >= 0) {
          if(f++ == 0) {
            printstr("::");
           }
        } else {
            if(f > 0) {
              f = -1;
            } else if(i > 0) {
                printstr(":");
            }
          printhex(a);
        }
      }
      printstrln("]");
#else
      printstr("IP Address: ");
      printint(ipconfig.ipaddr[0]);printstr(".");
      printint(ipconfig.ipaddr[1]);printstr(".");
      printint(ipconfig.ipaddr[2]);printstr(".");
      printint(ipconfig.ipaddr[3]);printstr("\n");
#endif
      }
      return;
    case XTCP_IFDOWN:
    case XTCP_ALREADY_HANDLED:
      return;
    default:
      break;
    }

  // Check if the connection is a http connection
  if (conn->local_port == 80) {
    switch (conn->event)
      {
      case XTCP_NEW_CONNECTION:
        httpd_init_state(tcp_svr, conn);
        break;
      case XTCP_RECV_DATA:
        httpd_recv(tcp_svr, conn);
        break;
      case XTCP_SENT_DATA:
      case XTCP_REQUEST_DATA:
      case XTCP_RESEND_DATA:
          httpd_send(tcp_svr, conn);
          break;
      case XTCP_TIMED_OUT:
      case XTCP_ABORTED:
      case XTCP_CLOSED:
          httpd_free_state(conn);
          break;
      default:
        // Ignore anything else
        break;
      }
    conn->event = XTCP_ALREADY_HANDLED;
  }
  ////
  return;
}