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); } }
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); } }