Exemplo n.º 1
0
void
Process_upnphttp(struct upnphttp * h)
{
	char * h_tmp;
	char buf[2048];
	int n;

	if(!h)
		return;
	switch(h->state)
	{
	case EWaitingForHttpRequest:
#ifdef ENABLE_HTTPS
		if(h->ssl) {
			n = SSL_read(h->ssl, buf, sizeof(buf));
		} else {
			n = recv(h->socket, buf, sizeof(buf), 0);
		}
#else
		n = recv(h->socket, buf, sizeof(buf), 0);
#endif
		if(n<0)
		{
#ifdef ENABLE_HTTPS
			if(h->ssl) {
				int err;
				err = SSL_get_error(h->ssl, n);
				if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
				{
					syslog(LOG_ERR, "SSL_read() failed");
					syslogsslerr();
					h->state = EToDelete;
				}
			} else {
#endif
			if(errno != EAGAIN &&
			   errno != EWOULDBLOCK &&
			   errno != EINTR)
			{
				syslog(LOG_ERR, "recv (state0): %m");
				h->state = EToDelete;
			}
			/* if errno is EAGAIN, EWOULDBLOCK or EINTR, try again later */
#ifdef ENABLE_HTTPS
			}
#endif
		}
		else if(n==0)
		{
			syslog(LOG_WARNING, "HTTP Connection closed unexpectedly");
			h->state = EToDelete;
		}
		else
		{
			const char * endheaders;
			/* if 1st arg of realloc() is null,
			 * realloc behaves the same as malloc() */
			h_tmp = (char *)realloc(h->req_buf, n + h->req_buflen + 1);
			if (h_tmp == NULL)
			{
				syslog(LOG_WARNING, "Unable to allocate new memory for h->req_buf)");
				h->state = EToDelete;
			}
			else
			{
				h->req_buf = h_tmp;
				memcpy(h->req_buf + h->req_buflen, buf, n);
				h->req_buflen += n;
				h->req_buf[h->req_buflen] = '\0';
			}
			/* search for the string "\r\n\r\n" */
			endheaders = findendheaders(h->req_buf, h->req_buflen);
			if(endheaders)
			{
				/* at this point, the request buffer (h->req_buf)
				 * is guaranteed to contain the \r\n\r\n character sequence */
				h->req_contentoff = endheaders - h->req_buf + 4;
				ProcessHttpQuery_upnphttp(h);
			}
		}
		break;
	case EWaitingForHttpContent:
#ifdef ENABLE_HTTPS
		if(h->ssl) {
			n = SSL_read(h->ssl, buf, sizeof(buf));
		} else {
			n = recv(h->socket, buf, sizeof(buf), 0);
		}
#else
		n = recv(h->socket, buf, sizeof(buf), 0);
#endif
		if(n<0)
		{
#ifdef ENABLE_HTTPS
			if(h->ssl) {
				int err;
				err = SSL_get_error(h->ssl, n);
				if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
				{
					syslog(LOG_ERR, "SSL_read() failed");
					syslogsslerr();
					h->state = EToDelete;
				}
			} else {
#endif
			if(errno != EAGAIN &&
			   errno != EWOULDBLOCK &&
			   errno != EINTR)
			{
				syslog(LOG_ERR, "recv (state1): %m");
				h->state = EToDelete;
			}
			/* if errno is EAGAIN, EWOULDBLOCK or EINTR, try again later */
#ifdef ENABLE_HTTPS
			}
#endif
		}
		else if(n==0)
		{
			syslog(LOG_WARNING, "HTTP Connection closed inexpectedly");
			h->state = EToDelete;
		}
		else
		{
			void * tmp = realloc(h->req_buf, n + h->req_buflen);
			if(!tmp)
			{
				syslog(LOG_ERR, "memory allocation error %m");
				h->state = EToDelete;
			}
			else
			{
				h->req_buf = tmp;
				memcpy(h->req_buf + h->req_buflen, buf, n);
				h->req_buflen += n;
				if((h->req_buflen - h->req_contentoff) >= h->req_contentlen)
				{
					ProcessHTTPPOST_upnphttp(h);
				}
			}
		}
		break;
	case ESendingContinue:
		if(SendResp_upnphttp(h))
			h->state = EWaitingForHttpContent;
		break;
	case ESendingAndClosing:
		SendRespAndClose_upnphttp(h);
		break;
	default:
		syslog(LOG_WARNING, "Unexpected state: %d", h->state);
	}
}
Exemplo n.º 2
0
void
Process_upnphttp(struct upnphttp * h)
{
	char buf[2048];
	int n;
	if(!h)
		return;
	switch(h->state)
	{
	case 0:
		n = recv(h->socket, buf, 2048, 0);
		if(n<0)
		{
			syslog(LOG_ERR, "recv (state0): %m");
			h->state = 100;
		}
		else if(n==0)
		{
			syslog(LOG_WARNING, "HTTP Connection closed inexpectedly");
			h->state = 100;
		}
		else
		{
			const char * endheaders;
			/* if 1st arg of realloc() is null,
			 * realloc behaves the same as malloc() */
			h->req_buf = (char *)realloc(h->req_buf, n + h->req_buflen + 1);
			memcpy(h->req_buf + h->req_buflen, buf, n);
			h->req_buflen += n;
			h->req_buf[h->req_buflen] = '\0';
			/* search for the string "\r\n\r\n" */
			endheaders = findendheaders(h->req_buf, h->req_buflen);
			if(endheaders)
			{
				h->req_contentoff = endheaders - h->req_buf + 4;
				ProcessHttpQuery_upnphttp(h);
			}
		}
		break;
	case 1:
		n = recv(h->socket, buf, 2048, 0);
		if(n<0)
		{
			syslog(LOG_ERR, "recv (state1): %m");
			h->state = 100;
		}
		else if(n==0)
		{
			syslog(LOG_WARNING, "HTTP Connection closed inexpectedly");
			h->state = 100;
		}
		else
		{
			/*fwrite(buf, 1, n, stdout);*/	/* debug */
			h->req_buf = (char *)realloc(h->req_buf, n + h->req_buflen);
			memcpy(h->req_buf + h->req_buflen, buf, n);
			h->req_buflen += n;
			if((h->req_buflen - h->req_contentoff) >= h->req_contentlen)
			{
				ProcessHTTPPOST_upnphttp(h);
			}
		}
		break;
	default:
		syslog(LOG_WARNING, "Unexpected state: %d", h->state);
	}
}
Exemplo n.º 3
0
/* Parse and process Http Query
 * called once all the HTTP headers have been received,
 * so it is guaranteed that h->req_buf contains the \r\n\r\n
 * character sequence */
static void
ProcessHttpQuery_upnphttp(struct upnphttp * h)
{
	static const struct {
		const char * path;
		char * (* f)(int *);
	} path_desc[] = {
		{ ROOTDESC_PATH, genRootDesc},
		{ WANIPC_PATH, genWANIPCn},
		{ WANCFG_PATH, genWANCfg},
#ifdef HAS_DUMMY_SERVICE
		{ DUMMY_PATH, NULL},
#endif
#ifdef ENABLE_L3F_SERVICE
		{ L3F_PATH, genL3F},
#endif
#ifdef ENABLE_6FC_SERVICE
		{ WANIP6FC_PATH, gen6FC},
#endif
#ifdef ENABLE_DP_SERVICE
		{ DP_PATH, genDP},
#endif
		{ NULL, NULL}
	};
	char HttpCommand[16];
	char HttpUrl[128];
	char * HttpVer;
	char * p;
	int i;
	p = h->req_buf;
	if(!p)
		return;
	/* note : checking (*p != '\r') is enough to avoid runing off the
	 * end of the buffer, because h->req_buf is guaranteed to contain
	 * the \r\n\r\n character sequence */
	for(i = 0; i<15 && *p != ' ' && *p != '\r'; i++)
		HttpCommand[i] = *(p++);
	HttpCommand[i] = '\0';
	while(*p==' ')
		p++;
	for(i = 0; i<127 && *p != ' ' && *p != '\r'; i++)
		HttpUrl[i] = *(p++);
	HttpUrl[i] = '\0';
	while(*p==' ')
		p++;
	HttpVer = h->HttpVer;
	for(i = 0; i<15 && *p != '\r'; i++)
		HttpVer[i] = *(p++);
	HttpVer[i] = '\0';
	syslog(LOG_INFO, "HTTP REQUEST : %s %s (%s)",
	       HttpCommand, HttpUrl, HttpVer);
	ParseHttpHeaders(h);
	if(strcmp("POST", HttpCommand) == 0)
	{
		h->req_command = EPost;
		ProcessHTTPPOST_upnphttp(h);
	}
	else if(strcmp("GET", HttpCommand) == 0)
	{
		h->req_command = EGet;
		for(i=0; path_desc[i].path; i++) {
			if(strcasecmp(path_desc[i].path, HttpUrl) == 0) {
				if(path_desc[i].f)
					sendXMLdesc(h, path_desc[i].f);
				else
#ifdef HAS_DUMMY_SERVICE
					sendDummyDesc(h);
#else
					continue;
#endif
				return;
			}
		}
		if(0 == memcmp(HttpUrl, "/ctl/", 5)) {
			/* 405 Method Not Allowed
			 * Allow: POST */
			h->respflags = FLAG_ALLOW_POST;
			Send405(h);
			return;
		}
#ifdef ENABLE_EVENTS
		if(0 == memcmp(HttpUrl, "/evt/", 5)) {
			/* 405 Method Not Allowed
			 * Allow: SUBSCRIBE, UNSUBSCRIBE */
			h->respflags = FLAG_ALLOW_SUB_UNSUB;
			Send405(h);
			return;
		}
#endif
		syslog(LOG_NOTICE, "%s not found, responding ERROR 404", HttpUrl);
		Send404(h);
	}
#ifdef ENABLE_EVENTS
	else if(strcmp("SUBSCRIBE", HttpCommand) == 0)
	{
		h->req_command = ESubscribe;
		ProcessHTTPSubscribe_upnphttp(h, HttpUrl);
	}
	else if(strcmp("UNSUBSCRIBE", HttpCommand) == 0)
	{
		h->req_command = EUnSubscribe;
		ProcessHTTPUnSubscribe_upnphttp(h, HttpUrl);
	}
#else
	else if(strcmp("SUBSCRIBE", HttpCommand) == 0)
	{
		syslog(LOG_NOTICE, "SUBSCRIBE not implemented. ENABLE_EVENTS compile option disabled");
		Send501(h);
	}
#endif
	else
	{
		syslog(LOG_NOTICE, "Unsupported HTTP Command %s", HttpCommand);
		Send501(h);
	}
}
Exemplo n.º 4
0
/* Parse and process Http Query 
 * called once all the HTTP headers have been received. */
static void
ProcessHttpQuery_upnphttp(struct upnphttp * h)
{
	char HttpCommand[16];
	char HttpUrl[128];
	char * HttpVer;
	char * p;
	int i;
	p = h->req_buf;
	if(!p)
		return;
	for(i = 0; i<15 && *p != ' ' && *p != '\r'; i++)
		HttpCommand[i] = *(p++);
	HttpCommand[i] = '\0';
	while(*p==' ')
		p++;
	for(i = 0; i<127 && *p != ' ' && *p != '\r'; i++)
		HttpUrl[i] = *(p++);
	HttpUrl[i] = '\0';
	while(*p==' ')
		p++;
	HttpVer = h->HttpVer;
	for(i = 0; i<15 && *p != '\r'; i++)
		HttpVer[i] = *(p++);
	HttpVer[i] = '\0';
	syslog(LOG_INFO, "HTTP REQUEST : %s %s (%s)",
	       HttpCommand, HttpUrl, HttpVer);
	ParseHttpHeaders(h);
	if(strcmp("POST", HttpCommand) == 0)
	{
		h->req_command = EPost;
		ProcessHTTPPOST_upnphttp(h);
	}
	else if(strcmp("GET", HttpCommand) == 0)
	{
		h->req_command = EGet;
		if(strcmp(ROOTDESC_PATH, HttpUrl) == 0)
		{
			sendXMLdesc(h, genRootDesc);
		}
		else if(strcmp(WANIPC_PATH, HttpUrl) == 0)
		{
			sendXMLdesc(h, genWANIPCn);
		}
		else if(strcmp(WANCFG_PATH, HttpUrl) == 0)
		{
			sendXMLdesc(h, genWANCfg);
		}
#ifdef HAS_DUMMY_SERVICE
		else if(strcmp(DUMMY_PATH, HttpUrl) == 0)
		{
			sendDummyDesc(h);
		}
#endif
#ifdef ENABLE_L3F_SERVICE
		else if(strcmp(L3F_PATH, HttpUrl) == 0)
		{
			sendXMLdesc(h, genL3F);
		}
#endif
		else
		{
			syslog(LOG_NOTICE, "%s not found, responding ERROR 404", HttpUrl);
			Send404(h);
		}
	}
#ifdef ENABLE_EVENTS
	else if(strcmp("SUBSCRIBE", HttpCommand) == 0)
	{
		h->req_command = ESubscribe;
		ProcessHTTPSubscribe_upnphttp(h, HttpUrl);
	}
	else if(strcmp("UNSUBSCRIBE", HttpCommand) == 0)
	{
		h->req_command = EUnSubscribe;
		ProcessHTTPUnSubscribe_upnphttp(h, HttpUrl);
	}
#else
	else if(strcmp("SUBSCRIBE", HttpCommand) == 0)
	{
		syslog(LOG_NOTICE, "SUBSCRIBE not implemented. ENABLE_EVENTS compile option disabled");
		Send501(h);
	}
#endif
	else
	{
		syslog(LOG_NOTICE, "Unsupported HTTP Command %s", HttpCommand);
		Send501(h);
	}
}