libUPnP 1.14.19
Data Structures | Macros | Typedefs | Functions
httpreadwrite.c File Reference
#include "config.h"
#include "httpreadwrite.h"
#include "UpnpExtraHeaders.h"
#include "UpnpFileInfo.h"
#include "UpnpInet.h"
#include "UpnpIntTypes.h"
#include "UpnpStdInt.h"
#include "membuffer.h"
#include "sock.h"
#include "statcodes.h"
#include "unixutil.h"
#include "upnp.h"
#include "upnpapi.h"
#include "uri.h"
#include "webserver.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include "posix_overwrites.h"
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
Include dependency graph for httpreadwrite.c:

Data Structures

struct  HTTPCONNECTIONHANDLE
 

Macros

#define CHUNK_HEADER_SIZE   (size_t)10
 
#define CHUNK_TAIL_SIZE   (size_t)10
 
#define DEFAULT_TCP_CONNECT_TIMEOUT   5
 
#define SIZE_RANGE_BUFFER   50
 

Typedefs

typedef struct HTTPCONNECTIONHANDLE http_connection_handle_t
 

Functions

static int Check_Connect_And_Wait_Connection (SOCKET sock, int connect_res)
 Checks socket connection and wait if it is not connected. It should be called just after connect.
 
static int private_connect (SOCKET sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
 
static int get_hoststr (const char *url_str, const char **hoststr, size_t *hostlen)
 
static void copy_msg_headers (LinkedList *msgHeaders, UpnpString *headers)
 
int http_FixUrl (uri_type *url, uri_type *fixed_url)
 Validates URL.
 
int http_FixStrUrl (const char *urlstr, size_t urlstrlen, uri_type *fixed_url)
 Parses URL and then validates URL.
 
SOCKET http_Connect (uri_type *destination_url, uri_type *url)
 Gets destination address from URL and then connects to the remote end.
 
int http_RecvMessage (SOCKINFO *info, http_parser_t *parser, http_method_t request_method, int *timeout_secs, int *http_error_code)
 Get the data on the socket and take actions based on the read data to modify the parser objects buffer.
 
int http_SendMessage (SOCKINFO *info, int *TimeOut, const char *fmt,...)
 Sends a message to the destination based on the format parameter.
 
int http_RequestAndResponse (uri_type *destination, const char *request, size_t request_length, http_method_t req_method, int timeout_secs, http_parser_t *response)
 
int http_Download (const char *url_str, int timeout_secs, char **document, size_t *doc_length, char *content_type)
 
int MakeGenericMessage (http_method_t method, const char *url_str, membuffer *request, uri_type *url, int contentLength, const char *contentType, const UpnpString *headers)
 
static int ReadResponseLineAndHeaders (SOCKINFO *info, http_parser_t *parser, int *timeout_secs, int *http_error_code)
 Parses already exiting data. If not complete reads more data on the connected socket. The read data is then parsed. The same methid is carried out for headers.
 
int http_HttpGetProgress (void *Handle, size_t *length, size_t *total)
 
int http_CancelHttpGet (void *Handle)
 
int http_OpenHttpConnection (const char *url_str, void **Handle, int timeout)
 Opens a connection to the server.
 
int http_MakeHttpRequest (Upnp_HttpMethod method, const char *url_str, void *Handle, UpnpString *headers, const char *contentType, int contentLength, int timeout)
 Makes a HTTP request using a connection previously created by UpnpOpenHttpConnection.
 
int http_WriteHttpRequest (void *Handle, char *buf, size_t *size, int timeout)
 Writes the content of a HTTP request initiated by a UpnpMakeHttpRequest call. The end of the content should be indicated by a call to UpnpEndHttpRequest.
 
int http_EndHttpRequest (void *Handle, int timeout)
 Indicates the end of a HTTP request previously made by UpnpMakeHttpRequest.
 
int http_GetHttpResponse (void *Handle, UpnpString *headers, char **contentType, int *contentLength, int *httpStatus, int timeout)
 Gets the response from the server using a connection previously created by UpnpOpenHttpConnection.
 
int http_ReadHttpResponse (void *Handle, char *buf, size_t *size, int timeout)
 Reads the content of a response using a connection previously created by UpnpOpenHttpConnection.
 
int http_CloseHttpConnection (void *Handle)
 Closes the connection created with UpnpOpenHttpConnection and frees any memory associated with the connection.
 
int http_SendStatusResponse (SOCKINFO *info, int http_status_code, int request_major_version, int request_minor_version)
 
int http_MakeMessage (membuffer *buf, int http_major_version, int http_minor_version, const char *fmt,...)
 Generate an HTTP message based on the format that is specified in the input parameters.
 
void http_CalcResponseVersion (int request_major_vers, int request_minor_vers, int *response_major_vers, int *response_minor_vers)
 
int MakeGetMessageEx (const char *url_str, membuffer *request, uri_type *url, struct SendInstruction *pRangeSpecifier)
 
int http_OpenHttpGetEx (const char *url_str, void **Handle, char **contentType, int *contentLength, int *httpStatus, int lowRange, int highRange, int timeout)
 
void get_sdk_info (char *info, size_t infoSize)
 

Detailed Description

Purpose: This file defines the functionality making use of the http. It defines functions to receive messages, process messages, send messages.

Function Documentation

◆ Check_Connect_And_Wait_Connection()

static int Check_Connect_And_Wait_Connection ( SOCKET  sock,
int  connect_res 
)
static

Checks socket connection and wait if it is not connected. It should be called just after connect.

Returns
0 if successful, else -1.
Parameters
[in]socksocket.
[in]connect_resresult of connect.

References memptr::buf, membuffer::buf, Check_Connect_And_Wait_Connection(), memptr::length, membuffer::length, http_header_t::name, sock_make_blocking(), sock_make_no_blocking(), UPNP_E_INVALID_URL, UPNP_E_SUCCESS, and http_header_t::value.

Referenced by Check_Connect_And_Wait_Connection().

◆ http_CloseHttpConnection()

int http_CloseHttpConnection ( void *  handle)

Closes the connection created with UpnpOpenHttpConnection and frees any memory associated with the connection.

Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: handle, or is not a valid pointer.
  • UPNP_E_SOCKET_READ: An error or timeout occurred reading from a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
Parameters
[in]HandleThe handle of the connection to close, created by the call to UpnpOpenHttpPost.

References sock_destroy(), UPNP_E_INVALID_PARAM, and UPNP_E_SUCCESS.

Referenced by UpnpCloseHttpConnection(), and UpnpCloseHttpPost().

◆ http_Connect()

SOCKET http_Connect ( uri_type destination_url,
uri_type url 
)

Gets destination address from URL and then connects to the remote end.

Returns
Socket descriptor on success, or on error:
  • UPNP_E_OUTOF_SOCKET
  • UPNP_E_SOCKET_CONNECT
Parameters
[in]destination_urlURL containing destination information.
[out]urlFixed and corrected URL.

References http_FixUrl(), INVALID_SOCKET, UPNP_E_OUTOF_SOCKET, UPNP_E_SOCKET_CONNECT, UpnpCloseSocket, and UpnpPrintf().

Referenced by notify_send_and_recv().

◆ http_EndHttpRequest()

int http_EndHttpRequest ( void *  handle,
int  timeout 
)

Indicates the end of a HTTP request previously made by UpnpMakeHttpRequest.

Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: handle is not a valid pointer.
  • UPNP_E_OUTOF_MEMORY: Insufficient resources exist to download this file.
  • UPNP_E_SOCKET_ERROR: Error occured allocating a socket and resources or an error occurred binding a socket.
  • UPNP_E_SOCKET_WRITE: An error or timeout occurred writing to a socket.
  • UPNP_E_SOCKET_CONNECT: An error occurred connecting a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
Parameters
[in]HandleThe handle to the connection.
[in]timeoutThe time out value sent with the request during which a response is expected from the receiver, failing which, an error is reported. If value is negative, timeout is infinite.

References sock_write(), UPNP_E_INVALID_PARAM, UPNP_E_SOCKET_WRITE, and UPNP_E_SUCCESS.

Referenced by UpnpCloseHttpPost(), and UpnpEndHttpRequest().

◆ http_FixStrUrl()

int http_FixStrUrl ( const char *  urlstr,
size_t  urlstrlen,
uri_type fixed_url 
)

Parses URL and then validates URL.

Returns
  • UPNP_E_INVALID_URL
  • UPNP_E_SUCCESS
Parameters
[in]urlstrCharacter string as a URL.
[in]urlstrlenLength of the character string.
[out]fixed_urlFixed and corrected URL.

References http_FixUrl(), parse_uri(), and UPNP_E_INVALID_URL.

Referenced by gena_subscribe(), gena_unsubscribe(), and http_OpenHttpConnection().

◆ http_FixUrl()

int http_FixUrl ( uri_type url,
uri_type fixed_url 
)

Validates URL.

Returns
  • UPNP_E_INVALID_URL
  • UPNP_E_SUCCESS
Parameters
[in]urlURL to be validated and fixed.
[out]fixed_urlURL after being fixed.

References HOSTPORT::text, token_string_casecmp(), UPNP_E_INVALID_URL, and UPNP_E_SUCCESS.

Referenced by http_Connect(), http_FixStrUrl(), and http_MakeMessage().

◆ http_GetHttpResponse()

int http_GetHttpResponse ( void *  handle,
UpnpString headers,
char **  contentType,
int *  contentLength,
int *  httpStatus,
int  timeout 
)

Gets the response from the server using a connection previously created by UpnpOpenHttpConnection.

Note
Memory for contentType is only valid until the next call to the HTTP API for the same connection.
Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: Either handle, contentType, contentLength or httpStatus is not a valid pointer.
  • UPNP_E_INVALID_URL: The url is not a valid URL.
  • UPNP_E_OUTOF_MEMORY: Insufficient resources exist to download this file.
  • UPNP_E_NETWORK_ERROR: A network error occurred.
  • UPNP_E_SOCKET_WRITE: An error or timeout occurred writing to a socket.
  • UPNP_E_SOCKET_READ: An error or timeout occurred reading from a socket.
  • UPNP_E_SOCKET_BIND: An error occurred binding a socket.
  • UPNP_E_SOCKET_CONNECT: An error occurred connecting a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
  • UPNP_E_BAD_RESPONSE: A bad response was received from the remote server.
Parameters
[in]HandleThe handle of the connection created by the call to UpnpOpenHttpConnection.
[in]headersHeaders sent by the server for the response. If NULL then the headers are not copied.
[out]contentTypeA buffer to store the media type of the item.
[out]contentLengthA pointer to store the length of the item.
[out]httpStatusThe status returned on receiving a response message.
[in]timeoutThe time out value sent with the request during which a response is expected from the server, failing which, an error is reported back to the user. If value is negative, timeout is infinite.

References memptr::buf, http_message_t::headers, PARSE_CONTINUE_1, PARSE_OK, PARSE_SUCCESS, ReadResponseLineAndHeaders(), http_message_t::status_code, UPNP_E_BAD_RESPONSE, and UPNP_E_SUCCESS.

Referenced by UpnpCloseHttpPost(), and UpnpGetHttpResponse().

◆ http_MakeHttpRequest()

int http_MakeHttpRequest ( Upnp_HttpMethod  method,
const char *  url,
void *  handle,
UpnpString headers,
const char *  contentType,
int  contentLength,
int  timeout 
)

Makes a HTTP request using a connection previously created by UpnpOpenHttpConnection.

Note
Trying to make another request while a request is already being processed results in undefined behavior. It's up to the user to end a previous request by calling UpnpEndHttpRequest.
Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: Either url, handle or contentType is not a valid pointer.
  • UPNP_E_INVALID_URL: The url is not a valid URL.
  • UPNP_E_OUTOF_MEMORY: Insufficient resources exist to download this file.
  • UPNP_E_SOCKET_ERROR: Error occured allocating a socket and resources or an error occurred binding a socket.
  • UPNP_E_SOCKET_WRITE: An error or timeout occurred writing to a socket.
  • UPNP_E_SOCKET_CONNECT: An error occurred connecting a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
Parameters
[in]url_strThe URL to use to make the request. The URL should use the same host and scheme used to create the connection.
[in]HandleThe handle to the connection.
[in]headersHeaders to be used for the request. Each header should be terminated by a CRLF as specified in the HTTP specification. If NULL then the default headers will be used.
[in]contentTypeThe media type of content being sent. Can be NULL.
[in]contentLengthThe length of the content being sent, in bytes. Set to UPNP_USING_CHUNKED to use chunked encoding, or UPNP_UNTIL_CLOSE to avoid specifying the content length to the server. In this case the request is considered unfinished until the connection is closed.
[in]timeoutThe time out value sent with the request during which a response is expected from the receiver, failing which, an error is reported. If value is negative, timeout is infinite.

References membuffer::buf, http_SendMessage(), membuffer::length, UPNP_E_INVALID_PARAM, and UPNP_E_SUCCESS.

Referenced by UpnpMakeHttpRequest(), and UpnpOpenHttpPost().

◆ http_MakeMessage()

int http_MakeMessage ( membuffer buf,
int  http_major_version,
int  http_minor_version,
const char *  fmt,
  ... 
)

Generate an HTTP message based on the format that is specified in the input parameters.

Format types:
        'B':    arg = int status_code           -- appends content-length,
content-type and HTML body for given code. 'b': arg1 = const char *buf; arg2 =
size_t buf_length memory ptr
        'C':    (no args)                       -- appends a HTTP CONNECTION:
close header depending on major, minor version. 'c':    (no args)
-- appends CRLF "\r\n"
        'D':    (no args)                       -- appends HTTP DATE: header
        'd':    arg = int number                -- appends decimal number
        'G':    arg = range information         -- add range header
        'h':    arg = off_t number              -- appends off_t number
        'K':    (no args)                       -- add chunky header
        'L':    arg = language information      -- add Content-Language header
if Accept-Language header is not empty and if WEB_SERVER_CONTENT_LANGUAGE is not
empty 'N':      arg1 = off_t content_length     -- content-length header 'q':
arg1 = http_method_t            -- request start line and HOST header arg2 =
(uri_type *) 'Q':       arg1 = http_method_t;           -- start line of request
                arg2 = char* url;
                arg3 = size_t url_length
        'R':    arg = int status_code           -- adds a response start line
        'S':    (no args)                       -- appends HTTP SERVER: header
        's':    arg = const char *              -- C_string
        'T':    arg = char * content_type;      -- format e.g: "text/html";
content-type header
        't':    arg = time_t * gmt_time         -- appends time in RFC 1123 fmt
        'U':    (no args)                       -- appends HTTP USER-AGENT:
header
        'X':    arg = const char *              -- useragent; "redsonic" HTTP
X-User-Agent: useragent 
Returns
  • 0 - On Success
  • UPNP_E_OUTOF_MEMORY
  • UPNP_E_INVALID_URL

References DOMString, http_FixUrl(), http_MakeMessage(), HOSTPORT::text, UPNP_E_INVALID_URL, UPNP_E_OUTOF_MEMORY, UpnpExtraHeaders_get_resp(), and UpnpPrintf().

Referenced by CreateServicePacket(), gena_subscribe(), gena_unsubscribe(), genaNotify(), http_MakeMessage(), notify_send_and_recv(), process_request(), respond_ok(), send_action_response(), send_error_response(), send_var_query_response(), and web_server_callback().

◆ http_OpenHttpConnection()

int http_OpenHttpConnection ( const char *  url,
void **  handle,
int  timeout 
)

Opens a connection to the server.

The SDK allocates the memory for handle, the application is responsible for freeing this memory.

Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: Either url, or handle is not a valid pointer.
  • UPNP_E_INVALID_URL: The url is not a valid URL.
  • UPNP_E_OUTOF_MEMORY: Insufficient resources exist to download this file.
  • UPNP_E_SOCKET_ERROR: Error occured allocating a socket and resources or an error occurred binding a socket.
  • UPNP_E_SOCKET_WRITE: An error or timeout occurred writing to a socket.
  • UPNP_E_SOCKET_CONNECT: An error occurred connecting a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
Parameters
[in]url_strThe URL which contains the host, and the scheme to make the connection.
[in,out]HandleA pointer in which to store the handle for this connection. This handle is required for futher operations over this connection.
[in]timeoutThe time out value sent with the request during which a response is expected from the receiver, failing which, an error is reported. If value is negative, timeout is infinite.

References http_FixStrUrl(), INVALID_SOCKET, sock_destroy(), sock_init(), token_string_casecmp(), UPNP_E_INVALID_PARAM, UPNP_E_OUTOF_MEMORY, UPNP_E_SOCKET_CONNECT, UPNP_E_SOCKET_ERROR, and UPNP_E_SUCCESS.

Referenced by UpnpOpenHttpConnection(), and UpnpOpenHttpPost().

◆ http_ReadHttpResponse()

int http_ReadHttpResponse ( void *  handle,
char *  buf,
size_t *  size,
int  timeout 
)

Reads the content of a response using a connection previously created by UpnpOpenHttpConnection.

Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: Either handle, buf or size is not a valid pointer.
  • UPNP_E_BAD_RESPONSE: A bad response was received from the remote server.
  • UPNP_E_BAD_HTTPMSG: Either the request or response was in the incorrect format.
  • UPNP_E_CANCELED: another thread called UpnpCancelHttpGet.
Note: In case of return values, the status code parameter of the passed in handle value may provide additional information on the return value.
Parameters
[in]HandleThe handle of the connection created by the call to UpnpOpenHttpConnection.
[in,out]bufThe buffer to store the read item.
[in,out]sizeThe size of the buffer to be read.
[in]timeoutThe time out value sent with the request during which a response is expected from the server, failing which, an error is reported back to the user. If value is negative, timeout is infinite.

References http_message_t::amount_discarded, membuffer::buf, scanner_t::cursor, http_message_t::entity, http_parser_t::entity_start_position, http_parser_t::http_error_code, memptr::length, http_message_t::msg, PARSE_CONTINUE_1, PARSE_FAILURE, PARSE_INCOMPLETE, PARSE_INCOMPLETE_ENTITY, PARSE_SUCCESS, sock_read(), UPNP_E_BAD_HTTPMSG, UPNP_E_BAD_RESPONSE, UPNP_E_CANCELED, UPNP_E_INVALID_PARAM, UPNP_E_SUCCESS, and UpnpPrintf().

Referenced by UpnpReadHttpGet(), and UpnpReadHttpResponse().

◆ http_RecvMessage()

int http_RecvMessage ( SOCKINFO info,
http_parser_t parser,
http_method_t  request_method,
int *  timeout_secs,
int *  http_error_code 
)

Get the data on the socket and take actions based on the read data to modify the parser objects buffer.

If an error is reported while parsing the data, the error code is passed in the http_errr_code parameter.

Parameters: IN SOCKINFO info; Socket information object OUT http_parser_t parser; HTTP parser object IN http_method_t request_method; HTTP request method IN OUT int* timeout_secs; time out OUT int* http_error_code; HTTP error code returned

Returns
UPNP_E_SUCCESS UPNP_E_BAD_HTTPMSG

References membuffer::buf, g_maxContentLength, http_parser_t::http_error_code, http_message_t::msg, PARSE_CONTINUE_1, PARSE_FAILURE, PARSE_INCOMPLETE_ENTITY, PARSE_NO_MATCH, PARSE_SUCCESS, sock_read(), UPNP_E_BAD_HTTPMSG, UPNP_E_OUTOF_MEMORY, UPNP_E_SUCCESS, and UpnpPrintf().

Referenced by notify_send_and_recv().

◆ http_SendMessage()

int http_SendMessage ( SOCKINFO info,
int *  timeout_secs,
const char *  fmt,
  ... 
)

Sends a message to the destination based on the format parameter.

fmt types:

  • 'f': arg = "const char *" file name
  • 'b': arg1 = "const char *" mem_buffer; arg2 = "size_t" buffer length.
  • 'I': arg = "struct SendInstruction *"

E.g.:

       char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
       char *filename = "foo.dat";
       int status = http_SendMessage(tcpsock, "bf",
        buf, strlen(buf),       // args for memory buffer
        filename);              // arg for file
Returns
  • UPNP_E_OUTOF_MEMORY
  • UPNP_E_FILE_READ_ERROR
  • UPNP_E_SUCCESS

References VirtualDirCallbacks::close, SendInstruction::Cookie, VirtualDirCallbacks::open, PRIzd, VirtualDirCallbacks::read, SendInstruction::ReadSendSize, SendInstruction::RequestCookie, VirtualDirCallbacks::seek, sock_write(), UPNP_E_FILE_READ_ERROR, UPNP_E_INTERNAL_ERROR, UPNP_E_OUTOF_MEMORY, UpnpPrintf(), and virtualDirCallback.

Referenced by http_MakeHttpRequest(), notify_send_and_recv(), respond_ok(), send_action_response(), send_error_response(), send_var_query_response(), and web_server_callback().

◆ http_WriteHttpRequest()

int http_WriteHttpRequest ( void *  handle,
char *  buf,
size_t *  size,
int  timeout 
)

Writes the content of a HTTP request initiated by a UpnpMakeHttpRequest call. The end of the content should be indicated by a call to UpnpEndHttpRequest.

Returns
An integer representing one of the following:
  • UPNP_E_SUCCESS: The operation completed successfully.
  • UPNP_E_INVALID_PARAM: Either handle, buf or size is not a valid pointer.
  • UPNP_E_SOCKET_WRITE: An error or timeout occurred writing to a socket.
  • UPNP_E_OUTOF_SOCKET: Too many sockets are currently allocated.
Parameters
[in]HandleThe handle of the connection created by the call to UpnpOpenHttpConnection.
[in]bufThe buffer containing date to be written.
[in]sizeThe size, in bytes of buf.
[in]timeoutA timeout value sent with the request during which a response is expected from the server, failing which, an error is reported. If value is negative, timeout is infinite.

References sock_write(), UPNP_E_INVALID_PARAM, UPNP_E_OUTOF_MEMORY, and UPNP_E_SUCCESS.

Referenced by UpnpWriteHttpPost(), and UpnpWriteHttpRequest().

◆ ReadResponseLineAndHeaders()

static int ReadResponseLineAndHeaders ( SOCKINFO info,
http_parser_t parser,
int *  timeout_secs,
int *  http_error_code 
)
static

Parses already exiting data. If not complete reads more data on the connected socket. The read data is then parsed. The same methid is carried out for headers.

Returns
integer:
  • PARSE_OK - On Success
  • PARSE_FAILURE - Failure to parse data correctly
  • UPNP_E_BAD_HTTPMSG - Socker read() returns an error
Parameters
infoSocket information object.
parserHTTP Parser object.
timeout_secsTime out value.
http_error_codeHTTP errror code returned.

References http_parser_t::http_error_code, http_message_t::msg, PARSE_FAILURE, PARSE_INCOMPLETE, PARSE_OK, sock_read(), and UPNP_E_BAD_HTTPMSG.

Referenced by http_GetHttpResponse().