miniupnpd: Support Expect: 100-continue for POST HTTP requests
This commit is contained in:
parent
9d94d08bd8
commit
8b8772eed1
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in New Issue