📄 http_client.c
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000 Intel Corporation// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// * Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.// * Neither name of Intel Corporation nor the names of its contributors// may be used to endorse or promote products derived from this software// without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.///////////////////////////////////////////////////////////////////////////////// $Revision: 1.1.1.5 $// $Date: 2001/06/15 00:21:55 $// //Utility functions for url parsing//and connecting to an http server as a client#include "./genlib/http_client/http_client.h"//*************************************************************************//* Name: copy_sockaddr_in//*//* Description: Copies one socket address into another.//*//* In: struct sockaddr_in *in, struct sockadd_in *out //*//* Out: The fields of out are set the same as in.//*//* Return Codes: None//* Error Codes: None //*************************************************************************void copy_sockaddr_in(const struct sockaddr_in *in, struct sockaddr_in *out){ bzero(out->sin_zero,8); out->sin_family=in->sin_family; out->sin_port=in->sin_port; out->sin_addr.s_addr=in->sin_addr.s_addr;}//*************************************************************************//* Name: copy_token//*//* Description: Tokens are generally pointers into other strings//* this copies the offset and size from a token (in)//* relative to one string (in_base) into a token (out)//* relative to another string (out_base)//*//* In: char * in_base, token * in, char * out_base //*//* Out: The fields of out are set relative to out_base.//*//* Return Codes: None //* Error Codes: None //*************************************************************************void copy_token(const token *in, const char * in_base, token * out, char * out_base){ out->size=in->size; out->buff = out_base + (in->buff-in_base);}//*************************************************************************//* Name: copy_URL_list//*//* Description: Copies one URL_list into another.//* This includes dynamically allocating the out->URLs //* field (the full string),//* and the structures used to hold the parsedURLs.//* This memory MUST be freed by the caller through: //* free_URL_list(&out)//*//* In: URL_list *in, URL_list *out//*//* Out: out->URLs contains a newly allocated copy of in->URls//* out->parsedURLs contains a newly allocated copy of //* out->parsedURls//*//* Return Codes: HTTP_SUCCESS //* Error Codes: UPNP_E_OUTOF_MEMORY //*************************************************************************int copy_URL_list( URL_list *in, URL_list *out){ int len = strlen(in->URLs)+1; int i=0; out->URLs=NULL; out->parsedURLs=NULL; out->size=0; out->URLs= (char *) malloc (len); out->parsedURLs= (uri_type *) malloc (sizeof(uri_type) * in->size); if ( (out->URLs==NULL) || (out->parsedURLs==NULL)) return UPNP_E_OUTOF_MEMORY; memcpy(out->URLs,in->URLs,len); for (i=0;i<in->size;i++) { //copy the parsed uri out->parsedURLs[i].type=in->parsedURLs[i].type; copy_token(&in->parsedURLs[i].scheme,in->URLs, &out->parsedURLs[i].scheme, out->URLs); out->parsedURLs[i].path_type=in->parsedURLs[i].path_type; copy_token(&in->parsedURLs[i].pathquery,in->URLs, &out->parsedURLs[i].pathquery,out->URLs); copy_token(&in->parsedURLs[i].fragment,in->URLs, &out->parsedURLs[i].fragment,out->URLs); copy_token(&in->parsedURLs[i].hostport.text, in->URLs,&out->parsedURLs[i].hostport.text, out->URLs); copy_sockaddr_in(&in->parsedURLs[i].hostport.IPv4address, &out->parsedURLs[i].hostport.IPv4address); } out->size=in->size; return HTTP_SUCCESS;}//*************************************************************************//* Name: free_URL_list//*//* Description: Frees the memory associated with a URL_list.//* Frees the dynamically allocated members of of list.//* Does NOT free the pointer to the list itself //* ( i.e. does NOT free(list))//* In: URL_list *list//*//* Out: list->URLs is freed //* list->parsedURLs is freed//*//* Return Codes: None//* Error Codes: None //************************************************************************* void free_URL_list(URL_list * list){ if (list->URLs) free(list->URLs); if (list->parsedURLs) free(list->parsedURLs); list->size=0;}//*************************************************************************//* Name: print_uri//*//* Description: Function useful in debugging for printing a parsed uri.//* Compiled out with DBGONLY macro. //* In: uri_type *in//*//* Out: prints the tokens making up a uri to the screen.//*//* Return Codes: None//* Error Codes: None //*************************************************************************DBGONLY(void print_uri( uri_type *in, Dbg_Level level, Dbg_Module Module, char *DbgFileName,int DbgLineNo){ FILE *fd = GetDebugFile(level,Module); if (!fd) return; if (DbgFileName) { //get lock pthread_mutex_lock(&GlobalDebugMutex); UpnpDisplayFileAndLine(fd,DbgFileName,DbgLineNo); } fprintf(fd," Scheme: "); print_token(&in->scheme,level,Module,NULL,0); fprintf(fd," Host/Port: "); print_token(&in->hostport.text,level,Module,NULL,0); fprintf(fd," PathQuery: "); print_token(&in->pathquery,level,Module,NULL,0); fprintf(fd," Fragment: "); print_token(&in->fragment,level,Module,NULL,0); fflush(fd); if (DbgFileName) { pthread_mutex_unlock(&GlobalDebugMutex); }})//*************************************************************************//* Name: print_token//*//* Description: Function useful in debugging for printing a token.//* Compiled out with DBGONLY macro. //* In: token *in//*//* Out: prints the token. ("Token Size: %d\n (then actual token //* between ' '\n)//*//* Return Codes: None//* Error Codes: None //*************************************************************************DBGONLY(void print_token(token * in,Dbg_Level level, Dbg_Module Module, char *DbgFileName, int DbgLineNo){ int i=0; FILE *fd = GetDebugFile(level,Module); if (!fd) return; if (DbgFileName) { //get lock pthread_mutex_lock(&GlobalDebugMutex); UpnpDisplayFileAndLine(fd,DbgFileName,DbgLineNo); } fprintf(fd,"Token Size : %d \'",in->size); for (i=0;i<in->size;i++) { fprintf(fd,"%c",in->buff[i]); } fprintf(fd,"%c",'\''); fprintf(fd,"%c",'\n'); fflush(fd); if (DbgFileName) { pthread_mutex_unlock(&GlobalDebugMutex); }})//*************************************************************************//* Name: token_string_casecmp//*//* Description: Compares a null terminated string to a token (irrespective of case)//*//* In: token * in1, char * in2//*//* Out: returns 0 if equal//*//* Return Codes: 0 if equal//* Error Codes: None //*************************************************************************int token_string_casecmp( token * in1, char * in2){ int in2_length=strlen(in2); if (in1->size!=in2_length) return 1; else return strncasecmp(in1->buff,in2,in1->size); }//*************************************************************************//* Name: token_string_cmp//*//* Description: Compares a null terminated string to a token (exact)//*//* In: token *in1, char *in2//*//* Out: 0 if equal//*//* Return Codes: 0 if equal//* Error Codes: None //*************************************************************************int token_string_cmp( token * in1, char * in2){ int in2_length=strlen(in2); if (in1->size!=in2_length) return 1; else return strncmp(in1->buff,in2,in1->size);}//*************************************************************************//* Name: token_cmp//*//* Description: Compares to tokens.//*//* In: token *in1, token *in2//*//* Out: 0 if equal//*//* Return Codes: 0 if equal//* Error Codes: None //*************************************************************************int token_cmp( token *in1, token *in2){ if (in1->size!=in2->size) return 1; else return memcmp(in1->buff,in2->buff,in1->size); }//*************************************************************************//* Name: is_reserved//*//* Description: Returns a 1 if a char is a RESERVED char//* as defined in http://www.ietf.org/rfc/rfc2396.txt//* (RFC explaining URIs)//*//* In: char in//*//* Out: 1 if reserved, 0 if not//*//* Return Codes: None//* Error Codes: None //*************************************************************************int is_reserved(char in){ if (strchr(RESERVED,in)) return 1; else return 0;}//*************************************************************************//* Name: is_mark//*//* Description: Returns a 1 if a char is a MARK char//* as defined in http://www.ietf.org/rfc/rfc2396.txt//* (RFC explaining URIs)//*//* In: char in//*//* Out: 1 if a Mark, O if not//*//* Return Codes: None//* Error Codes: None //*************************************************************************int is_mark(char in ){ if (strchr(MARK,in)) return 1; else return 0;}//*************************************************************************//* Name: is_unreserved//*//* Description: Returns a 1 if a char is an unreserved char//* as defined in http://www.ietf.org/rfc/rfc2396.txt//* (RFC explaining URIs)//*//* In: char in//*//* Out: 1 if unreserved, O if not//*//* Return Codes: None//* Error Codes: None //*************************************************************************int is_unreserved(char in){ if (isalnum(in) || (is_mark(in))) return 1; else return 0;}//*************************************************************************//* Name: is_escaped//*//* Description: Returns a 1 if a char[3] sequence is escaped//* as defined in http://www.ietf.org/rfc/rfc2396.txt//* (RFC explaining URIs)//* size of array is NOT checked (MUST be checked by caller)//*//* In: char *in//*//* Out: 1 if escaped, 0 if not//*//* Return Codes: None//* Error Codes: None //*************************************************************************int is_escaped( char * in){ if ( ( in[0]=='%') && (isxdigit(in[1])) && isxdigit(in[2])) { return 1; } else return 0;}//*************************************************************************//* Name: currentTmToHttpDate//*//* Description: Returns the current date/time in the fixed length format //* of RFC 822, updated by RFC 1123 (as described in HTTP 1.1//* http://www.w3.org/Protocols/rfc2616/rfc2616.htm //* format is: 'DATE: Mon, 30 Apr 1979 08:49:37 GMT\r\n\0'//* ('\r\n\0' is added for convenience)//*//* In: char * out (space for output , must be at least 38 //* characters)//*//* Out: the current date is put in out//*//* Return Codes: None//* Error Codes: None //*************************************************************************void currentTmToHttpDate(char *out){ char *month=NULL; char *day=NULL; time_t current_time; struct tm * current_tm; time(¤t_time); current_tm=gmtime(¤t_time); switch (current_tm->tm_mon) { case 0: month="Jan";break; case 1: month="Feb";break; case 2: month="Mar";break; case 3: month="Apr";break; case 4: month="May";break; case 5: month="Jun";break; case 6: month="Jul";break; case 7: month="Aug";break; case 8: month="Sep";break; case 9: month="Oct";break; case 10: month="Nov";break; case 11: month="Dec";break; } switch (current_tm->tm_wday) { case 0:day="Sun";break; case 1:day="Mon";break; case 2:day="Tue";break; case 3:day="Wed";break; case 4:day="Thu";break; case 5:day="Fri";break; case 6:day="Sat";break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -