miniupnpd: Support Expect: 100-continue for POST HTTP requests

This commit is contained in:
Thomas Bernard 2012-09-28 11:12:50 +02:00
parent 9d94d08bd8
commit 8b8772eed1
3 changed files with 75 additions and 0 deletions

View File

@ -7,6 +7,7 @@ $Id: Changelog.txt,v 1.309 2012/09/27 16:01:10 nanard Exp $
SetDefaultConnectionService() checks its argumnents in UPNP_STRICT mode SetDefaultConnectionService() checks its argumnents in UPNP_STRICT mode
Support for Accept-Language/Content-Language HTTP headers Support for Accept-Language/Content-Language HTTP headers
Content-Type is now text/xml; charset="utf-8" to conform with UDA v1.1 Content-Type is now text/xml; charset="utf-8" to conform with UDA v1.1
Support Expect: 100-continue for POST HTTP requests
2012/09/20: 2012/09/20:
Cleaning code in ipfw (Jardel Weyrich) Cleaning code in ipfw (Jardel Weyrich)

View File

@ -129,6 +129,19 @@ ParseHttpHeaders(struct upnphttp * h)
memcpy(h->accept_language, p, n); memcpy(h->accept_language, p, n);
h->accept_language[n] = '\0'; h->accept_language[n] = '\0';
} }
else if(strncasecmp(line, "expect", 6) == 0)
{
p = colon;
n = 0;
while(*p == ':' || *p == ' ' || *p == '\t')
p++;
while(p[n]>=' ')
n++;
if(strncasecmp(p, "100-continue", 12) == 0) {
h->respflags |= FLAG_CONTINUE;
syslog(LOG_DEBUG, "\"Expect: 100-Continue\" header detected");
}
}
#ifdef ENABLE_EVENTS #ifdef ENABLE_EVENTS
else if(strncasecmp(line, "Callback", 8)==0) else if(strncasecmp(line, "Callback", 8)==0)
{ {
@ -281,6 +294,7 @@ ProcessHTTPPOST_upnphttp(struct upnphttp * h)
{ {
if((h->req_buflen - h->req_contentoff) >= h->req_contentlen) if((h->req_buflen - h->req_contentoff) >= h->req_contentlen)
{ {
/* the request body is received */
if(h->req_soapActionOff > 0) if(h->req_soapActionOff > 0)
{ {
/* we can process the request */ /* we can process the request */
@ -301,6 +315,20 @@ ProcessHTTPPOST_upnphttp(struct upnphttp * h)
SendRespAndClose_upnphttp(h); SendRespAndClose_upnphttp(h);
} }
} }
else if(h->respflags & FLAG_CONTINUE)
{
/* Sending the 100 Continue response */
if(!h->res_buf) {
h->res_buf = malloc(256);
h->res_buf_alloclen = 256;
}
h->res_buflen = snprintf(h->res_buf, h->res_buf_alloclen,
"%s 100 Continue\r\n\r\n", h->HttpVer);
h->res_sent = 0;
h->state = ESendingContinue;
if(SendResp_upnphttp(h))
h->state = EWaitingForHttpContent;
}
else else
{ {
/* waiting for remaining data */ /* waiting for remaining data */
@ -645,6 +673,10 @@ Process_upnphttp(struct upnphttp * h)
} }
} }
break; break;
case ESendingContinue:
if(SendResp_upnphttp(h))
h->state = EWaitingForHttpContent;
break;
case ESendingAndClosing: case ESendingAndClosing:
SendRespAndClose_upnphttp(h); SendRespAndClose_upnphttp(h);
break; break;
@ -772,6 +804,41 @@ BuildResp_upnphttp(struct upnphttp * h,
BuildResp2_upnphttp(h, 200, "OK", body, bodylen); BuildResp2_upnphttp(h, 200, "OK", body, bodylen);
} }
int
SendResp_upnphttp(struct upnphttp * h)
{
ssize_t n;
while (h->res_sent < h->res_buflen)
{
n = send(h->socket, h->res_buf + h->res_sent,
h->res_buflen - h->res_sent, 0);
if(n<0)
{
if(errno == EINTR)
continue; /* try again immediatly */
if(errno == EAGAIN || errno == EWOULDBLOCK)
{
/* try again later */
return 0;
}
syslog(LOG_ERR, "send(res_buf): %m");
break; /* avoid infinite loop */
}
else if(n == 0)
{
syslog(LOG_ERR, "send(res_buf): %d bytes sent (out of %d)",
h->res_sent, h->res_buflen);
break;
}
else
{
h->res_sent += n;
}
}
return 1; /* finished */
}
void void
SendRespAndClose_upnphttp(struct upnphttp * h) SendRespAndClose_upnphttp(struct upnphttp * h)
{ {

View File

@ -34,6 +34,7 @@
enum httpStates { enum httpStates {
EWaitingForHttpRequest = 0, EWaitingForHttpRequest = 0,
EWaitingForHttpContent, EWaitingForHttpContent,
ESendingContinue,
ESendingAndClosing, ESendingAndClosing,
EToDelete = 100 EToDelete = 100
}; };
@ -86,6 +87,9 @@ struct upnphttp {
/* Include the "SID:" header in response */ /* Include the "SID:" header in response */
#define FLAG_SID 0x02 #define FLAG_SID 0x02
/* If set, the POST request included a "Expect: 100-continue" header */
#define FLAG_CONTINUE 0x40
/* If set, the Content-Type is set to text/xml, otherwise it is text/xml */ /* If set, the Content-Type is set to text/xml, otherwise it is text/xml */
#define FLAG_HTML 0x80 #define FLAG_HTML 0x80
@ -131,6 +135,9 @@ BuildResp2_upnphttp(struct upnphttp * h, int respcode,
const char * respmsg, const char * respmsg,
const char * body, int bodylen); const char * body, int bodylen);
int
SendResp_upnphttp(struct upnphttp *);
/* SendRespAndClose_upnphttp() */ /* SendRespAndClose_upnphttp() */
void void
SendRespAndClose_upnphttp(struct upnphttp *); SendRespAndClose_upnphttp(struct upnphttp *);