httpreadwrite.c

来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 2,067 行 · 第 1/5 页

C
2,067
字号
                // Create chunk for the current buffer.                if( Instr && Instr->IsChunkActive ) {                    // Copy CRLF at the end of the chunk                    memcpy( file_buf + num_read, "\r\n", 2 );                    // Hex length for the chunk size.                    sprintf( Chunk_Header, "%x", num_read );                    //itoa(num_read,Chunk_Header,16);                     strcat( Chunk_Header, "\r\n" );                    // Copy the chunk size header                     memcpy( file_buf - strlen( Chunk_Header ),                            Chunk_Header, strlen( Chunk_Header ) );                    // on the top of the buffer.                    //file_buf[num_read+strlen(Chunk_Header)] = NULL;                    //printf("Sending %s\n",file_buf-strlen(Chunk_Header));                    num_written = sock_write(                        info, file_buf - strlen( Chunk_Header ),                        num_read + strlen( Chunk_Header ) + 2, TimeOut );                    if( num_written !=                        num_read + ( int )strlen( Chunk_Header ) + 2 ) {                        // Send error nothing we can do.                        goto Cleanup_File;                    }                } else {                    // write data                    num_written = sock_write( info, file_buf, num_read, TimeOut );                    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,                        ">>> (SENT) >>>\n%.*s\n------------\n",                        ( int )num_written, file_buf );                    // Send error nothing we can do                    if( num_written != num_read ) {                        goto Cleanup_File;                    }                }            } // whileCleanup_File:            va_end( argp );            if( Instr && Instr->IsVirtualFile ) {                virtualDirCallback.close( Fp );	    } else {                fclose( Fp );	    }            free( ChunkBuf );            return RetVal;        } else if( c == 'b' ) {            // memory buffer            buf = va_arg(argp, char *);            buf_length = va_arg(argp, size_t);            if( buf_length > 0 ) {                num_written = sock_write( info, buf, buf_length, TimeOut );                UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,                    ">>> (SENT) >>>\n"		    "%.*s\nbuf_length=%d, num_written=%d\n"		    "------------\n",                    (int)buf_length, buf, (int)buf_length, num_written );                if( (size_t)num_written != buf_length ) {                    goto end;		}            }        }    }end:    va_end( argp );    free( ChunkBuf );    return 0;}/************************************************************************ * Function: http_RequestAndResponse * * Parameters: *	IN uri_type* destination;	Destination URI object which contains *					remote IP address among other elements *	IN const char* request;		Request to be sent *	IN size_t request_length;	Length of the request *	IN http_method_t req_method;	HTTP Request method *	IN int timeout_secs;		time out value *	OUT http_parser_t* response;	Parser object to receive the repsonse * * Description: *	Initiates socket, connects to the destination, sends a *	request and waits for the response from the remote end * * Returns: *	UPNP_E_SOCKET_ERROR * 	UPNP_E_SOCKET_CONNECT *	Error Codes returned by http_SendMessage *	Error Codes returned by http_RecvMessage ************************************************************************/inthttp_RequestAndResponse( IN uri_type * destination,                         IN const char *request,                         IN size_t request_length,                         IN http_method_t req_method,                         IN int timeout_secs,                         OUT http_parser_t * response ){    int tcp_connection;    int ret_code;    int http_error_code;    SOCKINFO info;    tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );    if( tcp_connection == -1 ) {        parser_response_init( response, req_method );        return UPNP_E_SOCKET_ERROR;    }    if( sock_init( &info, tcp_connection ) != UPNP_E_SUCCESS )    {        sock_destroy( &info, SD_BOTH );        parser_response_init( response, req_method );        return UPNP_E_SOCKET_ERROR;    }    // connect    ret_code = connect( info.socket,                        ( struct sockaddr * )&destination->hostport.                        IPv4address, sizeof( struct sockaddr_in ) );    if( ret_code == -1 ) {        sock_destroy( &info, SD_BOTH );        parser_response_init( response, req_method );        return UPNP_E_SOCKET_CONNECT;    }    // send request    ret_code = http_SendMessage( &info, &timeout_secs, "b",                                 request, request_length );    if( ret_code != 0 ) {        sock_destroy( &info, SD_BOTH );        parser_response_init( response, req_method );        return ret_code;    }    // recv response    ret_code = http_RecvMessage( &info, response, req_method,                                 &timeout_secs, &http_error_code );    sock_destroy( &info, SD_BOTH ); //should shutdown completely    return ret_code;}/************************************************************************ * Function: http_Download * * Parameters: *	IN const char* url_str;	String as a URL *	IN int timeout_secs;	time out value *	OUT char** document;	buffer to store the document extracted *				from the donloaded message. *	OUT int* doc_length;	length of the extracted document *	OUT char* content_type;	Type of content * * Description: *	Download the document message and extract the document  *	from the message. * * Return: int *	UPNP_E_SUCCESS *	UPNP_E_INVALID_URL ************************************************************************/inthttp_Download( IN const char *url_str,               IN int timeout_secs,               OUT char **document,               OUT int *doc_length,               OUT char *content_type ){    int ret_code;    uri_type url;    char *msg_start;    char *entity_start;    char *hoststr;    char *temp;    http_parser_t response;    size_t msg_length;    size_t hostlen;    memptr ctype;    size_t copy_len;    membuffer request;    char *urlPath = alloca( strlen( url_str ) + 1 );    //ret_code = parse_uri( (char*)url_str, strlen(url_str), &url );    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "DOWNLOAD URL : %s\n",        url_str );    ret_code =        http_FixStrUrl( ( char * )url_str, strlen( url_str ), &url );    if( ret_code != UPNP_E_SUCCESS ) {        return ret_code;    }    // make msg    membuffer_init( &request );    strcpy( urlPath, url_str );    hoststr = strstr( urlPath, "//" );    if( hoststr == NULL ) {        return UPNP_E_INVALID_URL;    }    hoststr += 2;    temp = strchr( hoststr, '/' );    if( temp == NULL ) {        return UPNP_E_INVALID_URL;    }    *temp = '\0';    hostlen = strlen( hoststr );    *temp = '/';    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen );    ret_code = http_MakeMessage(        &request, 1, 1,        "Q" "s" "bcDCUc",        HTTPMETHOD_GET, url.pathquery.buff, url.pathquery.size,        "HOST: ",        hoststr, hostlen );    if( ret_code != 0 ) {        UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,            "HTTP Makemessage failed\n" );            membuffer_destroy( &request );        return ret_code;    }    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HTTP Buffer:\n %s\n----------END--------\n", request.buf );    // get doc msg    ret_code =        http_RequestAndResponse( &url, request.buf, request.length,                                 HTTPMETHOD_GET, timeout_secs, &response );    if( ret_code != 0 ) {        httpmsg_destroy( &response.msg );        membuffer_destroy( &request );        return ret_code;    }    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n" );    print_http_headers( &response.msg );        // optional content-type        if( content_type ) {        if( httpmsg_find_hdr( &response.msg, HDR_CONTENT_TYPE, &ctype ) ==            NULL ) {            *content_type = '\0';   // no content-type        } else {            // safety            copy_len = ctype.length < LINE_SIZE - 1 ?                ctype.length : LINE_SIZE - 1;            memcpy( content_type, ctype.buf, copy_len );            content_type[copy_len] = '\0';        }    }    //    // extract doc from msg    //    if( ( *doc_length = ( int )response.msg.entity.length ) == 0 ) {        // 0-length msg        *document = NULL;    } else if( response.msg.status_code == HTTP_OK ) {        //LEAK_FIX_MK        // copy entity        entity_start = response.msg.entity.buf; // what we want        msg_length = response.msg.msg.length;   // save for posterity           msg_start = membuffer_detach( &response.msg.msg );  // whole msg        // move entity to the start; copy null-terminator too        memmove( msg_start, entity_start, *doc_length + 1 );        // save mem for body only        *document = realloc( msg_start, *doc_length + 1 );  //LEAK_FIX_MK        // *document = Realloc( msg_start,msg_length, *doc_length + 1 );//LEAK_FIX_MK        // shrink can't fail        assert( ( int )msg_length > *doc_length );        assert( *document != NULL );    }    if( response.msg.status_code == HTTP_OK ) {        ret_code = 0;           // success    } else {        // server sent error msg (not requested doc)        ret_code = response.msg.status_code;    }    httpmsg_destroy( &response.msg );    membuffer_destroy( &request );    return ret_code;}typedef struct HTTPPOSTHANDLE {    SOCKINFO sock_info;    int contentLength;} http_post_handle_t;/************************************************************************ * Function: MakePostMessage * * Parameters: *	const char *url_str;		String as a URL *	membuffer *request;		Buffer containing the request *	uri_type *url; 			URI object containing the scheme, *					path query token, etc. *	int contentLength;		length of content *	const char *contentType;	Type of content * * Description: *	Makes the message for the HTTP POST message * * Returns: *	UPNP_E_INVALID_URL * 	UPNP_E_INVALID_PARAM *	UPNP_E_SUCCESS ************************************************************************/intMakePostMessage( const char *url_str,                 membuffer * request,                 uri_type * url,                 int contentLength,                 const char *contentType ){    int ret_code = 0;    char *urlPath = alloca( strlen( url_str ) + 1 );    size_t hostlen = 0;    char *hoststr,     *temp;    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,                         "DOWNLOAD URL : %s\n", url_str );    ret_code =        http_FixStrUrl( ( char * )url_str, strlen( url_str ), url );    if( ret_code != UPNP_E_SUCCESS ) {        return ret_code;    }    // make msg    membuffer_init( request );    strcpy( urlPath, url_str );    hoststr = strstr( urlPath, "//" );    if( hoststr == NULL ) {        return UPNP_E_INVALID_URL;    }    hoststr += 2;    temp = strchr( hoststr, '/' );    if( temp == NULL ) {        return UPNP_E_INVALID_URL;    }    *temp = '\0';    hostlen = strlen( hoststr );    *temp = '/';    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen );    if( contentLength >= 0 ) {        ret_code = http_MakeMessage(            request, 1, 1,            "Q" "s" "bcDCU" "T" "Nc",            HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,            "HOST: ",	    hoststr, hostlen,            contentType,            (off_t)contentLength );    } else if( contentLength == UPNP_USING_CHUNKED ) {        ret_code = http_MakeMessage(            request, 1, 1,            "Q" "s" "bcDCU" "TKc",            HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,            "HOST: ",	    hoststr, hostlen,            contentType );    } else if( contentLength == UPNP_UNTIL_CLOSE ) {        ret_code = http_MakeMessage(            request, 1, 1,            "Q" "s" "bcDCU" "Tc",            HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size,            "HOST: ",	    hoststr, hostlen,            contentType );    } else {        ret_code = UPNP_E_INVALID_PARAM;    }    if( ret_code != 0 ) {        UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,            "HTTP Makemessage failed\n" );        membuffer_destroy( request );        return ret_code;    }    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HTTP Buffer:\n %s\n" "----------END--------\n",        request->buf );    return UPNP_E_SUCCESS;}/************************************************************************ * Function: http_WriteHttpPost * * Parameters: *	IN void *Handle:	Handle to the http post object *	IN char *buf:		Buffer to send to peer, if format used

⌨️ 快捷键说明

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