📄 http_client.c
字号:
} strcpy(out,"DATE: "); strcat(out,day); strcat(out,", "); sprintf(&out[strlen(out)],"%02d ",current_tm->tm_mday); strcat(out,month); sprintf(&out[strlen(out)]," %04d %02d:%02d:%02d GMT\r\n", (current_tm->tm_year+1900), current_tm->tm_hour,current_tm->tm_min, current_tm->tm_sec); }//*************************************************************************//* Name: parse_header_value//*//* Description: Parses the input for a header value.//* the header value is equal to all characters up to /r/n //* (end of line)//* with beginning and trailing whitespace, removed //* (TAB and ' ')//* The memory is NOT copied. The returned token simply //* points into the original char array. //* Assumes that the whitespace has been stripped from//* the beginning of value//* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: the size of the header value that was parsed, out.buff //* points into the original string. There is NO new memory //* created.//*//* Return Codes: None//* Error Codes: None //*************************************************************************int parse_header_value( char *in, token *out, int max_size){ int counter =0; char * finger=in; counter = parse_http_line(in,max_size); if (!counter) { out->size=0; out->buff=NULL; return 0; } counter-=2; finger+=(counter); //strip whitespace from end while ( (counter>=0) && ( (*finger==' ') || (*finger==TAB))) { counter--; finger--; } out->buff=in; out->size=counter; return counter;}//*************************************************************************//* Name: parse_http_line//*//* Description: Returns the number of characters between //* the first character of in, and the first \r\n//* sequence//* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: the size of the line (including \r\n)//* Return Codes: None//* Error Codes: 0 if no \r\n is found within the max_size //*************************************************************************int parse_http_line( char * in, int max_size){ int counter =0; while ( (counter+1<max_size) && ( (in[counter]!=CR) || (in[counter+1]!=LF))) counter++; if (counter>max_size-2 ) return 0; return counter+2;}//*************************************************************************//* Name: print_status_line//*//* Description: For Debugging: prints out a parsed status line.//*//* In: http_status *in//*//* Out: None//* Return Codes: None//* Error Codes: None //*************************************************************************DBGONLY(void print_status_line(http_status *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,"STATUS LINE\n"); fprintf(fd,"Status Code: \n"); print_token(&in->status_code,level,module,NULL,0); fprintf(fd,"Reason Phrase: \n"); print_token(&in->reason_phrase,level,module,NULL,0); fprintf(fd,"HTTP Version: \n"); print_token(&in->http_version,level,module,NULL,0); fflush(fd); if (DbgFileName) { pthread_mutex_unlock(&GlobalDebugMutex); }})//*************************************************************************//* Name: print_request_line//*//* Description: For Debugging: prints out a parsed request line.//*//* In: http_request *in//*//* Out: None//* Return Codes: None//* Error Codes: None //*************************************************************************DBGONLY(void print_request_line(http_request *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,"HTTP request line:\n"); fprintf(fd," Method: "); print_token(&in->method,level,module,NULL,0); fprintf(fd," Path URI: \n"); print_uri(&in->request_uri,level,module,NULL,0); fprintf(fd," HTTP Version: "); print_token(&in->http_version,level,module,NULL,0); fflush(fd); if (DbgFileName) { pthread_mutex_unlock(&GlobalDebugMutex); }})//*************************************************************************//* Name: parse_status_line//*//* Description: parses the status line of an http response//* In: char *in , http_status *out, int max_size //* ( to avoid running into bad memory)//*//* Out: returns size of line (including /r/n)//* Return Codes: None//* Error Codes: 0 if any piece is missing (NOTE: NO LWS is expected at //* beginning of in) //* values are not to be trusted//* if return code is zero //*************************************************************************int parse_status_line( char * in, http_status * out, int max_size){ int temp=0; int max_len=max_size; char * finger=in; int size=0; out->http_version.buff=NULL; out->http_version.size=0; out->status_code.buff=NULL; out->status_code.size=0; out->reason_phrase.buff=NULL; out->reason_phrase.size=0; if (! (temp=parse_not_LWS(in,&out->http_version,max_size))) { DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__, "PARSING STATUS LINE \n COULDN'T GET HTTP VERSION")); return 0; } finger+=temp; max_len-=temp; size+=temp; temp=parse_LWS(finger,max_len); max_len-=temp; finger+=temp; size+=temp; if (! (temp=parse_not_LWS(finger,&out->status_code,max_len))) { DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"PARSING STATUS LINE \n COULDN't GET STATUS CODE")); return 0; } finger+=temp; max_len-=temp; size+=temp; temp=parse_LWS(finger,max_len); max_len-=temp; finger+=temp; size+=temp; if (! (temp=parse_http_line(finger,max_len))) { DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"PARSING STATUS LINE \n COULDN'T GET REASON PHRASE")); return 0; } out->reason_phrase.buff=finger; //remove /r/n out->reason_phrase.size=temp-2; size+=temp; return size; }//*************************************************************************//* Name: parse_request_line//*//* Description: parses the request line of an http response//* In: char *in , http_status *out, int max_size //* ( to avoid running into bad memory)//*//* Out: returns size of line (including /r/n)//* Return Codes: None//* Error Codes: 0 if any piece is missing or bad (NOTE: //* NO LWS is expected at //* beginning of in) //* values are not to be trusted//* if return code is zero //*************************************************************************int parse_request_line( char * in, http_request * out, int max_size){ int temp=0; int max_len=max_size; char * finger=in; int size=0; token tempToken; out->http_version.buff=NULL; out->http_version.size=0; out->method.buff=NULL; out->method.size=0; if (! (temp=parse_token(in,&out->method,max_size))) { DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"PARSING REQUEST LINE \n COULDN'T GET METHOD")); return 0; } finger+=temp; max_len-=temp; size+=temp; temp=parse_LWS(finger,max_len); max_len-=temp; finger+=temp; size+=temp; //parse request URI (path) if (!(temp=parse_uri(finger,max_len,&out->request_uri))) { DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"PARSING REQUEST LINE \n COULDN't GET REQUEST URI")); return 0; } temp=parse_not_LWS(finger,&tempToken,max_len); max_len-=temp; finger+=temp; size+=temp; temp=parse_LWS(finger,max_len); max_len-=temp; finger+=temp; size+=temp; if (! (temp=parse_http_line(finger,max_len))) { DBGONLY(UpnpPrintf(UPNP_CRITICAL,API,__FILE__,__LINE__,"PARSING REQUEST LINE \n COULDN'T GET HTTP VERSION")); return 0; } //remove /r/n out->http_version.size=temp-2; out->http_version.buff=finger; size+=temp; return size; }//*************************************************************************//* Name: parse_not_LWS//*//* Description: Returns the number of characters between //* the first character of in, and the first LWS (for this //* function LWS: Tab //* or space )//* sets the value of the token.buff=in, token.size= (num of //* characters of nonLWS)//*//* Note: does not handle multiple line white space //* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: out->size (length of non LWS at beginning of in)//*//* Return Codes: None//* Error Codes: None //*************************************************************************int parse_not_LWS( char *in, token *out, int max_size){ int counter=0; while ( (counter<max_size) && (in[counter]!=' ') && (in[counter]!=TAB) ) counter++; out->buff=in; out->size=counter; return counter; }//*************************************************************************//* Name: parse_LWS//*//* Description: Returns the number of characters between //* the first character of in, and the first non LWS (LWS is //* TAB or SPACE)//* for this function//* //* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: length of LWS at beginning of in//* Return Codes: None//* Error Codes: None //*************************************************************************int parse_LWS( char * in, int max_size){ int counter=0; while ((counter<max_size) && ( (in[counter]==' ') || (in[counter]==TAB) )) { counter++; } return counter;}//*************************************************************************//* Name: parse_token//*//* Description: parses a token as defined in HTTP/1.1 //* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: out->size (length of token)//* Note: out->buff simply points to in. (no new memory)//* Return Codes: length of token//* Error Codes: 0 if no char is matched//*************************************************************************int parse_token( char * in, token * out, int max_size){ int counter=0; while ( ( counter<max_size) && (in[counter]>31) && (strchr(SEPARATORS,in[counter])==NULL) && (in[counter]!=127)) { counter++; } out->buff=in; out->size=counter; return counter;}//*************************************************************************//* Name: parse_uric//*//* Description: parses a string of uric characters starting at in[0]//* as defined in http://www.ietf.org/rfc/rfc2396.txt//* (RFC explaining URIs)//* In: char *in , int max_size (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: out->size (length of uric string)//* Note: out->buff simply points to in. (no new memory)//* Return Codes: length of uric string//* Error Codes: 0 if no char is matched. //*************************************************************************int parse_uric( char *in, int max, token *out){ int i=0; while ( (i<max) && ( ( is_unreserved(in[i])) || (is_reserved(in[i])) || ( (i+2<max) && (is_escaped(&in[i])) ) ) ) { i++; } out->size=i; out->buff=in; return i;}//*************************************************************************//* Name: parse_port//*//* Description: parses a port (i.e. '4000') and converts it into a network//* ordered unsigned short int.//* In: char *port , int max (max_size to be considered //* to avoid //* running into bad memory)//*//* Out: unsigned short int *out. (memory allocated by caller)//* //* Return Codes: Number of characters contained in the port value//* Error Codes: 0 if no char is matched. //*************************************************************************int parse_port(int max, char * port, unsigned short * out){ char * finger=port; char * max_ptr=finger+max;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -