예제 #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);
	}
}
예제 #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);
	}
}