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

📄 http_client.c

📁 UPnP的SDK源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	  begin_path+=begin_hostport;	}      else	return begin_path;			  	    }  else    {       out->hostport.IPv4address.sin_port=0;       out->hostport.IPv4address.sin_addr.s_addr=0;       out->hostport.text.size=0;       out->hostport.text.buff=0;       begin_path=begin_hostport;    }  begin_fragment=parse_uric(&in[begin_path],max-begin_path,&out->pathquery);    if ( (out->pathquery.size) && (out->pathquery.buff[0]=='/'))    {      out->path_type=ABS_PATH;    }  begin_fragment+=begin_path;   if ( (begin_fragment<max) && ( in[begin_fragment]=='#'))    {      begin_fragment++;      parse_uric(&in[begin_fragment],max-begin_fragment,&out->fragment);    }  else{    out->fragment.buff=NULL;    out->fragment.size=0;  }    return HTTP_SUCCESS;}//*************************************************************************//* Name: concat_socket_buffers//*//* Description:  concats a list of socket buffers (used to read data of //*               unknown size) into one buffer (out)//*               size of out is assumed to be large enough to hold the data//*               the caller is responsible for maintaining this//*//* In:           socket_buffer * head (head of the list of buffers)//*//* Out:          the concatenated socket_buffers are copied into out//*//* Return Codes: None//* Error Codes:  None   //*************************************************************************void concat_socket_buffers(socket_buffer * head, char * out){  socket_buffer *finger=head;  finger=head;  while (finger)    {      memcpy(out,finger->buff,finger->size);      out+=finger->size;      finger=finger->next;     }  }//*************************************************************************//* Name: free_socket_buffers//*//* Description:  frees the space allocated in a list of socket_buffers//*              //* In:           socket_buffer * head (head of list of buffers to free)//*//* Out:          None//*           //* Return Codes: None//* Error Codes:  None  //*************************************************************************void free_socket_buffers(socket_buffer * head){  socket_buffer * temp=NULL;  socket_buffer * finger=NULL;  if (head)    {      finger=head->next;      while (finger)	{	  temp=finger->next;	  free(finger);	  finger=temp;	}    }}//*************************************************************************//* Name: getHeaders//*//* Description:  Reads the header section of a http message (used in //*               transfer http) //*               returns a list of socket buffers and the content length//*               if a "CONTENT-LENGTH:" header is found. //*               reads until a line : "\r\n"//*              //* In:           socket_buffer * head (head of list of buffers)//*               int fd (socket)//*               int * ContentLength (space to place content length)//*               socket_buffer **tail (space to place end of socket buffer //*                                     list)//*               int * timeout (timeout for operation) (returns time //*                             remaining after operation)//*               //* Out:          total size of headers (memory contained in list of socket //*               buffers) memory in socket buffer list must be freed by//*               caller//*           //* Return Codes: >=0 SUCCESS , time of operation is subtracted//*                             from timeout//* Error Codes:  UPNP_E_OUTOF_MEMORY (memory failure)//*               UPNP_E_SOCKET_READ (error reading from socket , including //*                                   timeout) //*************************************************************************int getHeaders(int fd, int *ContentLength, socket_buffer* head,	       socket_buffer **tail, int *timeout){  socket_buffer *current=head;  socket_buffer *prev=NULL;  int total_size=0;   char  * invalidchar;  char * pat="CONTENT-LENGTH:";  char * pat2="TRANSFER-ENCODING: CHUNKED";  char * pat3="CONTENT";  int pat_len=strlen(pat);  int pat2_len=strlen(pat2);  int pat3_len=strlen(pat3);    head->next=NULL;  (*ContentLength)=-3;  (*tail)=NULL;  current->size=0;    while (  (current->size=readLine(fd,current->buff,SOCKET_BUFFER_SIZE,timeout)) >0)    {      total_size+=current->size;            //check for continuation of header over multiple lines      //this is a continuation if and only if the previous line was      //properly ended AND this line begins with a space or tab      //in this case the CRLF is removed from the previous line      if ( (current->buff[0]==' ')	   || (current->buff[0]==TAB))	{	  if (prev)	    {		if ( (prev->size>=2) && (prev->buff[prev->size-1]=='\n')		     && (prev->buff[prev->size-2]=='\r'))		  prev->size-=2;		DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"REMOVED CRLF FROM MULTILINE HEADER"));		total_size-=2;	    }	}      //make sure we only check these values after new lines      //just in case the previous value was so large that the CRLF was      //not detected before the SOCKET_BUFFER was filled      if  ( (!prev)	    || ( (prev) && (prev->size>=2) && (prev->buff[prev->size-1]=='\n')		 && (prev->buff[prev->size-2]=='\r')))	{	  if (!strncasecmp(pat3,current->buff,pat3_len))	    {	      DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"EXPECTING CONTENT"));	      if ((*ContentLength)==-3)		(*ContentLength)=-2;	    }	  if (!strncasecmp(pat2,current->buff,pat2_len))	    {	      DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"CONTENT IS CHUNKED"));	      //transfer-encoding:chunked	      (*ContentLength)=-1;	    }	  //if it is "Content-Length:" then get the length	  if (!strncasecmp(pat,current->buff,pat_len))	    {	      //if transfer-encoding chunked is already found then	      //ignore content length header	      if ((*ContentLength)!=-1)		{		  DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"CONTENT LENGTH FOUND"));		  (*ContentLength)=strtol(current->buff+pat_len					  ,&invalidchar,10);		  		  if (invalidchar==current->buff+pat_len)		    {		      (*ContentLength)=0;		      DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"Trouble getting Content Length"));		    }		}	    }	  	  	  //last \r\n	  if ( ( current->size==2) && (current->buff[0]=='\r')) 	    break;	}            current->next= (socket_buffer *) malloc(sizeof(socket_buffer));      if (!current->next)	{	  free_socket_buffers(head);	  return UPNP_E_OUTOF_MEMORY;	}            prev=current;      current=current->next;      current->next=NULL;      current->size=0;          }    if (current->size<0)    {      (*ContentLength)=0;      free_socket_buffers(head);      DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"ERROR READING SOCKET"));      return UPNP_E_SOCKET_READ;     }  if ((*ContentLength)==-3)    (*ContentLength)=0;    (*tail)=current;    return total_size;}//*************************************************************************//* Name: write_timeout//*//* Description:  writes bytes to a socket with a timeout//*              //* In:           int fd (socket)//*               void *buf (buffer to be sent)//*               size_t count (number of bytes to be sent)//*               int *timeout (timeout for operation)//*//* Out:          # of bytes sent. timeout is updated, time of operation//*               is subtracted from it.//*           //* Return Codes: >=0 success//* Error Codes:  -1 Timeout, <=0 Error return code of write()//*************************************************************************ssize_t write_timeout(int fd,  void *buf, size_t count, int *timeout){  fd_set wset;  struct timeval tv;  time_t current_time;  int writeable;  time_t new_time;  if ((*timeout)<=0)    {      return -1; //TIMEOUT    }  FD_ZERO(&wset);  FD_SET(fd,&wset);  tv.tv_sec=(*timeout);  tv.tv_usec = 0 ;  time(&current_time); //get current time    writeable=select(fd+1,NULL, &wset,NULL,&tv);  if (writeable>0)    {       time(&new_time);      (*timeout)-=(new_time-current_time);           return send(fd,buf,count,MSG_NOSIGNAL);    }  else    {      (*timeout)=0;      return -1; //TIMEOUT    }}//*************************************************************************//* Name: read_timeout//*//* Description:  read bytes to a socket with a timeout//*              //* In:           int fd (socket)//*               void *buf (buffer to store data)//*               size_t count (number of bytes to be read t)//*               int *timeout (timeout for operation)//*//* Out:          # of bytes read. timeout is updated, time of operation//*               is subtracted from it.//*           //* Return Codes: >=0 success//* Error Codes:  -1 Timeout, <=0 Error return code of read()//*************************************************************************ssize_t read_timeout(int fd,void *buf, size_t count, int * timeout){  fd_set rset;  struct timeval tv;  time_t current_time;  int readable;  time_t new_time;  if ((*timeout)<=0)    {      DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"TIMEOUT ON READ"));      return -1; //TIMEOUT    }    FD_ZERO(&rset);  FD_SET(fd, &rset);  tv.tv_sec=(*timeout);  tv.tv_usec = 0 ;  time(&current_time); //get current time    readable=select(fd+1,&rset, NULL,NULL,&tv);  if (readable>0)    {       time(&new_time);      (*timeout)-=(new_time-current_time);      return recv(fd,buf,count,0);    }  else    {      (*timeout)=0;      DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"TIMEOUT ON READ"));    return -1; //TIMEOUT    }    }//*************************************************************************//* Name: readLine//*//* Description:  reads characters from a socket until a newline is seen//*               appends a null to the output//* In:           int fd (socket)//*               char *out(buffer to store data)//*               int max (bytes in buffer)//*               int *timeout (timeout for operation)//*//* Out:          # of bytes read. timeout is updated, time of operation//*               is subtracted from it.//*           //* Return Codes: >=0 success//* Error Codes:  -1 Error reading from socket//*************************************************************************ssize_t readLine(int fd, char *out, int max, int *timeout){  char c;  ssize_t count=0,rc=0;  while ( (count<(max-1)) && ( (rc=read_timeout(fd,&c,1,timeout))==1) )    {      *out++=c;      count++;      if (c=='\n')	break;    }  if (rc<0)//error    {      return -1;    }  *out=0;  return count;}//*************************************************************************//* Name: read_http_response//*//* Description:  reads the http response from a socket, with a timeout//*               returns a dynamically allocated string (null terminated)//*               must be freed by caller.      //*        //* In:           int fd (socket)//*               char **out (memory allocated by function and pointer //*                           stored here)//*               int timeout (timeout for operation)//*//* Out:          http response is read and returned in null terminated //*               string, (*out). http headers and content are read//*               ONLY WORKS if "CONTENT LENGTH:" header is present.//*               otherwise content is NOT returned.//*           //* Return Codes: HTTP_SUCCESS on success//* Error Codes:  UPNP_E_OUTOF_MEMORY, memory error//*               UPNP_E_SOCKET_READ, socket read error, including//*               timeout//*************************************************************************int read_http_response(int fd, char **out, int timeout){  socket_buffer head;  socket_buffer *current=&head;  socket_buffer * header_tail=NULL;  int total_size=0;  int contentLength=0;  int Timeout=timeout;  int done =0;  int chunk_size=-1;  socket_buffer chunkSizebuff;  char *invalidchar;  int nextToRead=0;  head.next=NULL;    if ( ( (total_size=getHeaders(fd,&contentLength,&head,&header_tail,&Timeout)) >0))    {            current=header_tail;            if (contentLength==0)	{	  DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"NO CONTENT EXPECTED"));	  done=1;	}      while (!done)	{	  if ( (contentLength==-1)	       && ( chunk_size<=0))	    {	      DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"GETTING NEXT CHUNK SIZE"));	      //gobble up crlf	      if (chunk_size==0)		chunkSizebuff.size=		  readLine(fd,chunkSizebuff.buff,SOCKET_BUFFER_SIZE,&Timeout);	      	      if ((chunkSizebuff.size=readLine(fd,chunkSizebuff.buff,SOCKET_BUFFER_SIZE,&Timeout)) >0)		{		  chunk_size=strtol(chunkSizebuff.buff				      ,&invalidchar,16);		  DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"chunk size: %d\n",chunk_size);)		  if (invalidchar==chunkSizebuff.buff)		    chunk_size=0;			}	      else		chunk_size=0;	      if (chunk_size==0)		{		  done=1;		  break;

⌨️ 快捷键说明

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