⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upnphttp.c

📁 miniupnpd可以在嵌入式linux中实现upnp功能
💻 C
📖 第 1 页 / 共 2 页
字号:
		CloseSocket_upnphttp(h);	} else {	/* - add to the subscriber list	 * - respond HTTP/x.x 200 OK 	 * - Send the initial event message *//* Server:, SID:; Timeout: Second-(xx|infinite) */		if(h->req_Callback) {			sid = upnpevents_addSubscriber(path, h->req_Callback,			                               h->req_CallbackLen, h->req_Timeout);			h->respflags = FLAG_TIMEOUT;			if(sid) {				syslog(LOG_DEBUG, "generated sid=%s", sid);				h->respflags |= FLAG_SID;				h->req_SID = sid;				h->req_SIDLen = strlen(sid);			}			BuildResp_upnphttp(h, 0, 0);		} else {			/* subscription renew */			/* Invalid SID412 Precondition Failed. If a SID does not correspond to a known,un-expired subscription, the publisher must respondwith HTTP error 412 Precondition Failed. */			if(renewSubscription(h->req_SID, h->req_SIDLen, h->req_Timeout) < 0) {				BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0);			} else {				BuildResp_upnphttp(h, 0, 0);			}		}		SendResp_upnphttp(h);		CloseSocket_upnphttp(h);	}}static voidProcessHTTPUnSubscribe_upnphttp(struct upnphttp * h, const char * path){	syslog(LOG_DEBUG, "ProcessHTTPUnSubscribe %s", path);	syslog(LOG_DEBUG, "SID '%.*s'", h->req_SIDLen, h->req_SID);	/* Remove from the list */	if(upnpevents_removeSubscriber(h->req_SID, h->req_SIDLen) < 0) {		BuildResp2_upnphttp(h, 412, "Precondition Failed", 0, 0);	} else {		BuildResp_upnphttp(h, 0, 0);	}	SendResp_upnphttp(h);	CloseSocket_upnphttp(h);}#endif/* Parse and process Http Query  * called once all the HTTP headers have been received. */static voidProcessHttpQuery_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);	}}voidProcess_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);	}}static const char httpresphead[] =	"%s %d %s\r\n"	/*"Content-Type: text/xml; charset=\"utf-8\"\r\n"*/	"Content-Type: %s\r\n"	"Connection: close\r\n"	"Content-Length: %d\r\n"	/*"Server: miniupnpd/1.0 UPnP/1.0\r\n"*/	"Server: " MINIUPNPD_SERVER_STRING "\r\n"	;	/*"\r\n";*//*		"<?xml version=\"1.0\"?>\n"		"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "		"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"		"<s:Body>"		"</s:Body>"		"</s:Envelope>";*//* with response code and response message * also allocate enough memory */voidBuildHeader_upnphttp(struct upnphttp * h, int respcode,                     const char * respmsg,                     int bodylen){	int templen;	if(!h->res_buf)	{		templen = sizeof(httpresphead) + 128 + bodylen;		h->res_buf = (char *)malloc(templen);		h->res_buf_alloclen = templen;	}	h->res_buflen = snprintf(h->res_buf, h->res_buf_alloclen,	                         httpresphead, h->HttpVer,	                         respcode, respmsg,	                         (h->respflags&FLAG_HTML)?"text/html":"text/xml",							 bodylen);	/* Additional headers */#ifdef ENABLE_EVENTS	if(h->respflags & FLAG_TIMEOUT) {		h->res_buflen += snprintf(h->res_buf + h->res_buflen,		                          h->res_buf_alloclen - h->res_buflen,		                          "Timeout: Second-");		if(h->req_Timeout) {			h->res_buflen += snprintf(h->res_buf + h->res_buflen,			                          h->res_buf_alloclen - h->res_buflen,			                          "%d\r\n", h->req_Timeout);		} else {			h->res_buflen += snprintf(h->res_buf + h->res_buflen,			                          h->res_buf_alloclen - h->res_buflen,			                          "infinite\r\n");		}	}	if(h->respflags & FLAG_SID) {		h->res_buflen += snprintf(h->res_buf + h->res_buflen,		                          h->res_buf_alloclen - h->res_buflen,		                          "SID: %s\r\n", h->req_SID);	}#endif	h->res_buf[h->res_buflen++] = '\r';	h->res_buf[h->res_buflen++] = '\n';	if(h->res_buf_alloclen < (h->res_buflen + bodylen))	{		h->res_buf = (char *)realloc(h->res_buf, (h->res_buflen + bodylen));		h->res_buf_alloclen = h->res_buflen + bodylen;	}}voidBuildResp2_upnphttp(struct upnphttp * h, int respcode,                    const char * respmsg,                    const char * body, int bodylen){	BuildHeader_upnphttp(h, respcode, respmsg, bodylen);	if(body)		memcpy(h->res_buf + h->res_buflen, body, bodylen);	h->res_buflen += bodylen;}/* responding 200 OK ! */voidBuildResp_upnphttp(struct upnphttp * h,                        const char * body, int bodylen){	BuildResp2_upnphttp(h, 200, "OK", body, bodylen);}voidSendResp_upnphttp(struct upnphttp * h){	int n;	n = send(h->socket, h->res_buf, h->res_buflen, 0);	if(n<0)	{		syslog(LOG_ERR, "send(res_buf): %m");	}	else if(n < h->res_buflen)	{		/* TODO : handle correctly this case */		syslog(LOG_ERR, "send(res_buf): %d bytes sent (out of %d)",						n, h->res_buflen);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -