summaryrefslogtreecommitdiff
path: root/include/m_netlib.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/m_netlib.h')
-rw-r--r--include/m_netlib.h1730
1 files changed, 865 insertions, 865 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h
index b821af977a..8c3e1e1d24 100644
--- a/include/m_netlib.h
+++ b/include/m_netlib.h
@@ -1,865 +1,865 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (C) 2012-21 Miranda NG team (https://miranda-ng.org)
-Copyright (c) 2000-12 Miranda ICQ/IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef M_NETLIB_H__
-#define M_NETLIB_H__ 1
-
-#include "m_utils.h"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// this module was created in 0.1.2.2
-// All error codes are returned via GetLastError() (or WSAGetLastError():
-// they're the same).
-// This module is thread-safe where it is sensible for it to be so. This
-// basically means that you can call anything from any thread, but don't try
-// to predict what will happen if you try to recv() on the same connection from
-// two different threads at the same time.
-// Note that because the vast majority of the routines in this module return
-// a pointer, I have decided to diverge from the rest of Miranda and go with
-// the convention that functions return false on failure and nonzero on success.
-
-struct NETLIBHTTPREQUEST;
-struct NETLIBOPENCONNECTION;
-
-#define NETLIB_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.112 Safari/537.36"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Initialises the netlib for a set of connections
-// Returns a HNETLIBUSER to be used for future netlib calls, NULL on failure
-// NOTE: Netlib is loaded after any plugins, so you need to wait until
-// ME_SYSTEM_MODULESLOADED before calling this function
-// Netlib settings are stored under the module szSettingsModule
-// All netlib settings being with "NL".
-// The default settings for registered users that don't have any settings stored
-// in the database are the same as those displayed by the <All connections> page
-// of the netlib options page.
-// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME
-
-struct NETLIBUSER
-{
- char *szSettingsModule; // used for db settings and log
- MAllStrings szDescriptiveName; // used in options dialog, already translated
- DWORD flags;
- int minIncomingPorts; // only if NUF_INCOMING. Will be used for validation of user input.
-};
-
-#define NUF_INCOMING 0x01 // binds incoming ports
-#define NUF_OUTGOING 0x02 // makes outgoing plain connections
-#define NUF_NOOPTIONS 0x08 // don't create an options page for this. szDescriptiveName is never used.
-#define NUF_HTTPCONNS 0x10 // at least some connections are made for HTTP communication. Enables the HTTP proxy option in options.
-#define NUF_NOHTTPSOPTION 0x20 // disable the HTTPS proxy option in options. Use this if all communication is HTTP.
-#define NUF_UNICODE 0x40 // if set ptszDescriptiveName points to Unicode, otherwise it points to ANSI string
-
-EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_RegisterUser(const NETLIBUSER *pDescr);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Assign a Netlib user handle a set of dynamic HTTP headers to be used with all
-//
-// HTTP connections that enable the HTTP-use-sticky headers flag.
-// The headers persist until cleared with lParam = NULL.
-//
-// All memory should be allocated by the caller using malloc() from MS_SYSTEM_GET_MMI
-// Once it has passed to Netlib, Netlib is the owner of it, the caller should not refer to the memory
-// In any way after this point.
-//
-// NOTE: The szHeaders parameter should be a NULL terminated string following the HTTP header syntax.
-// This string will be injected verbatim, thus the user should be aware of setting strings that are not
-// headers. This service is NOT THREAD SAFE, only a single thread is expected to set the headers and a single
-// thread reading the pointer internally, stopping race conditions and mutual exclusion don't happen.
-//
-// Version 0.3.2a+ (2003/10/27)
-//
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SetStickyHeaders(HNETLIBUSER nlu, const char *szHeaders);
-
-/* Notes on HTTP gateway usage
-When a connection is initiated through an HTTP proxy using
-MS_NETLIB_OPENCONNECTION, netlib will GET nlu.szHttpGatewayHello and read
-the replied headers. Once this succeeds nlu.pfnHttpGatewayInit will be called
-with a valid handle to the connection, the NETLIBOPENCONNECTION structure that
-MS_NETLIB_OPENCONNECTION was called with, and the replied HTTP headers as its
-parameters. This function is responsible for recving and parsing the data then
-calling MS_NETLIB_SETHTTPPROXYINFO with the appropriate information.
-nlu.pfnHttpGatewayInit should return nonzero on success. If it returns zero
-then the entire connection attempt will return signalling failure. If your
-function needs to return an error code it can do so via SetLastError().
-If nlu.pfnHttpGatewayInit returns success without having called
-MS_NETLIB_SETHTTPPROXYINFO then the connection attempt will fail anyway.
-If you need more fine-tuned control over the GET/POST URLs than just appending
-sequence numbers you can call MS_NETLIB_SETHTTPPROXYINFO from within your
-wrap/unwrap functions (see below).
-
-Just prior to MS_NETLIB_OPENCONNECTION returning nlu.pfnHttpGatewayBegin is
-called with the handle to the connection and the NETLIBOPENCONNECTION structure
-as its parameters. This is for gateways that need special non-protocol
-initialisation. If you do send any packets in this function, you probably want
-to remember to use the MSG_NOHTTPGATEWAYWRAP flag. This function pointer can be
-NULL if this functionality isn't needed. This function must return nonzero on
-success. If it fails the connect attempt will return failure without changing
-LastError.
-
-Whenever MS_NETLIB_SEND is called on a connection through an HTTP proxy and
-the MSG_NOHTTPGATEWAYWRAP flags is not set and nlu.pfnHttpGatewayWrapSend is
-not NULL, nlu.pfnHttpGatewayWrapSend will be called *instead* of sending the
-data. It is this function's responsibility to wrap the sending data
-appropriately for transmission and call pfnNetlibSend to send it again.
-The flags parameter to nlu.pfnHttpGatewayWrapSend should be passed straight
-through to the pfnNetlibSend call. It has already been ORed with
-MSG_NOHTTPGATEWAYWRAP. nlu.pfnHttpGatewayWrapSend should return the a
-number of the same type as MS_NETLIB_SEND, ie the number of bytes sent or
-SOCKET_ERROR. The number of wrapping bytes should be subtracted so that the
-return value appears as if the proxy wasn't there.
-pfnNetlibSend() is identical to CallService(MS_NETLIB_SEND, ...) but it's
-quicker to call using this pointer than to do the CallService() lookup again.
-
-Whenever an HTTP reply is received inside MS_NETLIB_RECV the headers and data
-are read into memory. If the headers indicate success then the data is passed
-to nlu.pfnHttpGatewayUnwrapRecv (if it's non-NULL) for processing. This
-function should remove (and do other processing if necessary) all HTTP proxy
-specific headers and return a pointer to the buffer whose size is returned in
-*outBufLen. If the buffer needs to be resized then NetlibRealloc() should be
-used for that purpose, *not* your own CRT's realloc(). NetlibRealloc() behaves
-identically to realloc() so it's possible to free the original buffer and
-create a new one if that's the most sensible way to write your parser.
-If errors are encountered you should SetLastError() and return NULL;
-MS_NETLIB_RECV will return SOCKET_ERROR. If the passed buffer unwraps to
-contain no actual data you should set *outBufLen to 0 but make sure you return
-some non-NULL buffer that can be freed.
-
-When you call MS_NETLIB_SEND or MS_NETLIB_RECV from any of these functions, you
-should use the MSG_DUMPPROXY flag so that the logging is neat.
-*/
-
-#define PROXYTYPE_SOCKS4 1
-#define PROXYTYPE_SOCKS5 2
-#define PROXYTYPE_HTTP 3
-#define PROXYTYPE_HTTPS 4
-#define PROXYTYPE_IE 5
-
-struct NETLIBUSERSETTINGS
-{
- int cbSize; // to be filled in before calling
- int useProxy; // 1 or 0
- int proxyType; // a PROXYTYPE_
- char *szProxyServer; // can be NULL
- int wProxyPort; // host byte order
- int useProxyAuth; // 1 or 0. Always 0 for SOCKS4
- char *szProxyAuthUser; // can be NULL, always used by SOCKS4
- char *szProxyAuthPassword; // can be NULL
- int useProxyAuthNtlm; // 1 or 0, only used by HTTP, HTTPS
- int dnsThroughProxy; // 1 or 0
- int specifyIncomingPorts; // 1 or 0
- char *szIncomingPorts; // can be NULL. Of form "1024-1050, 1060-1070, 2000"
- int specifyOutgoingPorts; // 0.3.3a+
- char *szOutgoingPorts; // 0.3.3a+
- int enableUPnP; // 0.6.1+ only for NUF_INCOMING
- int validateSSL;
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets the user-configured settings for a netlib user
-//
-// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// The pointers referred to in the returned struct will remain valid until
-// the hUser handle is closed, or until the user changes the settings in the
-// options page, so it's best not to rely on them for too long.
-// Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *result);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-//Gets the user-configured settings for a netlib user idetified by name
-//
-//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-//This function behaves like Netlib_GetUserSettings but the user is identified
-//by the name provided by registration. When the name is not found NETLIBUSERSETTINGS is set to NULL.
-//Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Changes the user-configurable settings for a netlib user
-//
-// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// This function is only really useful for people that specify NUF_NOOPTIONS
-// and want to create their own options.
-// Even if a setting is not active (eg szProxyAuthPassword when useProxyAuth is
-// zero) that settings is still set for use in the options dialog.
-// Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *result);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-//Changes the user-configurable settings for a netlib user idetified by name
-//
-//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-//This function behaves like Netlib_SetUserSettings but the user is identified
-//by the name provided by registration. Nothing will be changed when the name is not found.
-//Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Closes a netlib handle
-//
-// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// This function should be called on all handles returned by netlib functions
-// once you are done with them. If it's called on a socket-type handle, the
-// socket will be closed.
-// Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE h);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Open a port and wait for connections on it
-//
-// Returns a HANDLE on success, NULL on failure
-// hUser should have been returned by MS_NETLIB_REGISTERUSER
-// This function does the equivalent of socket(), bind(), getsockname(),
-// listen(), accept()
-// Internally this function creates a new thread which waits around in accept()
-// for new connections. When one is received it calls nlb.pfnNewConnection *from
-// this new thread* and then loops back to wait again.
-// Close the returned handle to end the thread and close the open port.
-// Errors: ERROR_INVALID_PARAMETER, any returned by socket() or bind() or
-// listen() or getsockname()
-//
-// Notes:
-//
-// During development of 0.3.1a+ (2003/07/04) passing wPort != 0
-// will result in an attempt to bind on the port given in wPort
-// if this port is taken then you will get an error, so be sure to check
-// for such conditions.
-//
-// passing wPort != 0 is for people who need to open a set port for
-// daemon activities, usually passing wPort == 0 is what you want and
-// will result in a free port given by the TCP/IP socket layer and/or
-// seeded from the user selected port ranges.
-//
-// also note that wPort if != 0, will have be converted to network byte order
-//
-/* pExtra was added during 0.3.4+, prior its just two args, since we use the cdecl convention
-it shouldnt matter */
-
-typedef void (*NETLIBNEWCONNECTIONPROC)(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra);
-
-struct NETLIBBIND
-{
- NETLIBNEWCONNECTIONPROC pfnNewConnection;
-
- // function to call when there's a new connection. Params are: the
- // new connection, IP of remote machine (host byte order)
- DWORD dwInternalIP; // set on return, host byte order
- DWORD dwExternalIP; // set on return, host byte order
- WORD wPort, wExPort; // set on return, host byte order
- void *pExtra; // argument is sent to callback
-};
-
-EXTERN_C MIR_APP_DLL(HNETLIBBIND) Netlib_BindPort(HNETLIBUSER nlu, NETLIBBIND *nlb);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Open a connection
-//
-// Returns a HNETLIBCONN to the new connection on success, NULL on failure
-// hUser must have been returned by MS_NETLIB_REGISTERUSER
-// Internally this function is the equivalent of socket(), gethostbyname(),
-// connect()
-// If NLOCF_HTTP is set and hUser is configured for an HTTP or HTTPS proxy then
-// this function will connect() to the proxy server only, without performing any
-// initialisation conversation.
-// If hUser is configured for an HTTP proxy and does not support HTTP gateways
-// and you try to open a connection without specifying NLOCF_HTTP then this
-// function will first attempt to open an HTTPS connection, if that fails it
-// will try a direct connection, if that fails it will return failure with the
-// error from the connect() during the direct connection attempt.
-// Errors: ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(),
-// connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select()
-// ERROR_TIMEOUT (during proxy communication)
-// ERROR_BAD_FORMAT (very invalid proxy reply)
-// ERROR_ACCESS_DENIED (by proxy)
-// ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd)
-// ERROR_INVALID_ACCESS (proxy refused identd auth)
-// ERROR_INVALID_DATA (proxy returned invalid code)
-// ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported)
-// ERROR_GEN_FAILURE (socks5/https general failure)
-// ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported)
-// ERROR_INVALID_ADDRESS (socks5 address type not supported)
-// HTTP: anything from nlu.pfnHttpGatewayInit, nlu.pfnHttpGatewayBegin,
-// MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS
-
-#define NLOCF_HTTP 0x0001 // this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy.
-#define NLOCF_STICKYHEADERS 0x0002 // this connection should send the sticky headers associated with NetLib user apart of any HTTP request
-#define NLOCF_V2 0x0004 // this connection understands the newer structure, newer cbSize isnt enough
-#define NLOCF_UDP 0x0008 // this connection is UDP
-#define NLOCF_SSL 0x0010 // this connection is SSL
-
-struct NETLIBOPENCONNECTION
-{
- const char *szHost; // can contain the string representation of an IP
- WORD wPort; // host byte order
- DWORD flags;
- unsigned int timeout;
- /* optional, called in the context of the thread that issued the attempt, if it returns 0 the connection attempt is
- stopped, the remaining timeout value can also be adjusted */
- int (*waitcallback) (unsigned int *timeout);
-};
-
-EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const NETLIBOPENCONNECTION *nloc);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Sets the required information for an HTTP proxy connection
-//
-// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// This function is designed to be called from within pfnHttpGatewayInit
-// See notes below MS_NETLIB_REGISTERUSER.
-// Errors: ERROR_INVALID_PARAMETER
-
-#define NLHPIF_USEGETSEQUENCE 0x0001 // append sequence numbers to GET requests
-#define NLHPIF_USEPOSTSEQUENCE 0x0002 // append sequence numbers to POST requests
-#define NLHPIF_GETPOSTSAMESEQUENCE 0x0004 // GET and POST use the same sequence
-#define NLHPIF_HTTP11 0x0008 // HTTP 1.1 proxy
-
-struct NETLIBHTTPPROXYINFO
-{
- DWORD flags;
- int firstGetSequence, firstPostSequence;
- int combinePackets;
- char *szHttpPostUrl;
- char *szHttpGetUrl;
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SetHttpProxyInfo(HNETLIBCONN hConnection, const NETLIBHTTPPROXYINFO *nlhpi);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets the SOCKET associated with a netlib handle
-//
-// Returns the SOCKET on success, INVALID_SOCKET on failure
-// hNetlibHandle should have been returned by MS_NETLIB_BINDPORT or
-// MS_NETLIB_OPENCONNECTION only.
-// Be careful how you use this socket because you might be connected via an
-// HTTP proxy in which case calling send() or recv() will totally break things.
-// Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(UINT_PTR) Netlib_GetSocket(HNETLIBCONN hConnection);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define Netlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3)
-#define Netlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1)
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets HNETLIBUSER owner of a connection
-
-EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_GetConnNlu(HNETLIBCONN hConn);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets the fake User-Agent header field to make some sites happy
-
-EXTERN_C MIR_APP_DLL(char*) Netlib_GetUserAgent();
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Converts numerical representation of IP in SOCKADDR_INET into string representation with IP and port
-// IPv4 will be supplied in formats address:port or address
-// IPv6 will be supplied in formats [address]:port or [address]
-// Returns pointer to the string or NULL if not successful
-
-struct sockaddr_in;
-EXTERN_C MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr);
-EXTERN_C MIR_APP_DLL(bool) Netlib_StringToAddress(const char *str, sockaddr_in *addr);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets connection Information
-// IPv4 will be supplied in formats address:port or address
-// IPv6 will be supplied in formats [address]:port or [address]
-// Returns 0 if successful
-
-struct NETLIBCONNINFO
-{
- char szIpPort[64];
- unsigned dwIpv4;
- WORD wPort;
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Gets connection Information
-//
-// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array
-// the last element of the array is all 0s, 0 if not successful
-
-struct NETLIBIPLIST
-{
- unsigned cbNum;
- char szIp[1][64];
-};
-
-EXTERN_C MIR_APP_DLL(NETLIBIPLIST*) Netlib_GetMyIp(bool bGlobalOnly);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Send an HTTP request over a connection
-//
-// Returns number of bytes sent on success, SOCKET_ERROR on failure
-// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
-// Note that if you use NLHRF_SMARTAUTHHEADER and NTLM authentication is in use
-// then the full NTLM authentication transaction occurs, comprising sending the
-// domain, receiving the challenge, then sending the response.
-// nlhr.resultCode and nlhr.szResultDescr are ignored by this function.
-// Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND
-
-struct NETLIBHTTPHEADER
-{
- char *szName;
- char *szValue;
-};
-
-EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, const char *pszName);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define REQUEST_RESPONSE 0 // used by structure returned by MS_NETLIB_RECVHTTPHEADERS
-#define REQUEST_GET 1
-#define REQUEST_POST 2
-#define REQUEST_CONNECT 3
-#define REQUEST_HEAD 4
-#define REQUEST_PUT 5
-#define REQUEST_DELETE 6
-#define REQUEST_PATCH 7
-
-#define NLHRF_MANUALHOST 0x00000001 // do not remove any host and/or protocol portion of szUrl before sending it
-#define NLHRF_HTTP11 0x00000010 // use HTTP 1.1
-#define NLHRF_PERSISTENT 0x00000020 // preserve connection on exit, open connection provided in the nlc field of the reply
- // it should be supplied in nlc field of request for reuse or closed if not needed
-#define NLHRF_SSL 0x00000040 // use SSL connection
-#define NLHRF_NOPROXY 0x00000080 // do not use proxy server
-#define NLHRF_REDIRECT 0x00000100 // handle HTTP redirect requests (response 30x), the resulting url provided in szUrl of the response
-#define NLHRF_NODUMP 0x00010000 // never dump this to the log
-#define NLHRF_NODUMPHEADERS 0x00020000 // don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION)
-#define NLHRF_DUMPPROXY 0x00040000 // this transaction is a proxy communication. For dump filtering only.
-#define NLHRF_DUMPASTEXT 0x00080000 // dump posted and reply data as text. Headers are always dumped as text.
-#define NLHRF_NODUMPSEND 0x00100000 // do not dump sent message.
-
-struct NETLIBHTTPREQUEST
-{
- int cbSize;
- int requestType; // a REQUEST_
- DWORD flags;
- char *szUrl;
- NETLIBHTTPHEADER *headers; // If this is a POST request and headers
- // doesn't contain a Content-Length it'll be added automatically
- int headersCount;
- char *pData; // data to be sent in POST request.
- int dataLength; // must be 0 for REQUEST_GET/REQUEST_CONNECT
- int resultCode;
- char *szResultDescr;
- HNETLIBCONN nlc;
- int timeout;
-
- __forceinline const char *operator[](const char *pszName) {
- return Netlib_GetHeader(this, pszName);
- }
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SendHttpRequest(HNETLIBCONN hConnection, NETLIBHTTPREQUEST *pRec);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Receives HTTP headers
-//
-// Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on failure.
-// Call Netlib_FreeHttpRequest() to free this.
-// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
-// nlhr->pData = NULL and nlhr->dataLength = 0 always. The requested data should
-// be retrieved using MS_NETLIB_RECV once the header has been parsed.
-// If the headers haven't finished within 60 seconds the function returns NULL
-// and ERROR_TIMEOUT.
-// Errors: ERROR_INVALID_PARAMETER, any from MS_NETLIB_RECV or select()
-// ERROR_HANDLE_EOF (connection closed before headers complete)
-// ERROR_TIMEOUT (headers still not complete after 60 seconds)
-// ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank)
-// ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long)
-// ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line)
-
-EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int flags = 0);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Free the memory used by a NETLIBHTTPREQUEST structure
-//
-// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// This should only be called on structures returned by
-// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
-// arbitrary structure will have disastrous results.
-// Errors: ERROR_INVALID_PARAMETER
-
-EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST*);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// smart pointer for NETLIBHTTPREQUEST via a call of Netlib_FreeHttpRequest()
-
-#ifdef __cplusplus
-class NLHR_PTR
-{
-protected:
- NETLIBHTTPREQUEST *_p;
-
-public:
- __forceinline explicit NLHR_PTR(NETLIBHTTPREQUEST *p) : _p(p) {}
-
- __forceinline NETLIBHTTPREQUEST* operator=(INT_PTR i_p)
- {
- return operator=((NETLIBHTTPREQUEST*)i_p);
- }
- __forceinline NETLIBHTTPREQUEST* operator=(NETLIBHTTPREQUEST *p)
- {
- if (_p)
- Netlib_FreeHttpRequest(_p);
- _p = p;
- return _p;
- }
- __forceinline operator NETLIBHTTPREQUEST*() const { return _p; }
- __forceinline NETLIBHTTPREQUEST* operator->() const { return _p; }
- __forceinline ~NLHR_PTR()
- {
- Netlib_FreeHttpRequest(_p);
- }
-};
-
-struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
-{
- MHttpRequest();
- ~MHttpRequest();
-
- CMStringA m_szUrl;
- CMStringA m_szParam;
- void *pUserInfo = nullptr;
-
- void AddHeader(const char *szName, const char *szValue);
-};
-
-template <class T>
-class MTHttpRequest : public MHttpRequest
-{
-public:
- __forceinline MTHttpRequest()
- {}
-
- typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
- MTHttpRequestHandler m_pFunc = nullptr;
-};
-
-MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT_PARAM&);
-MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT64_PARAM&);
-MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const CHAR_PARAM&);
-MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
-
-#endif
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Do an entire HTTP transaction
-//
-// Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on failure.
-// Call Netlib_FreeHttpRequest() to free this.
-// hUser must have been returned by MS_NETLIB_REGISTERUSER
-// nlhr.szUrl should be a full HTTP URL. If it does not start with http:// , that
-// will be assumed (but it's best not to use this fact, for reasons of
-// extensibility).
-// This function is the equivalent of MS_NETLIB_OPENCONNECTION,
-// MS_NETLIB_SENDHTTPREQ, MS_NETLIB_RECVHTTPHEADERS, MS_NETLIB_RECV,
-// MS_NETLIB_CLOSEHANDLE
-// nlhr.headers will be augmented with the following headers unless they have
-// already been set by the caller:
-// "Host" (regardless of whether it is requested in nlhr.flags)
-// "User-Agent" (of the form "Miranda/0.1.2.2 (alpha)" or "Miranda/0.1.2.2")
-// "Content-Length" (for POSTs only. Set to nlhr.dataLength)
-// If you do not want to send one of these headers, create a nlhr.headers with
-// szValue = NULL.
-// In the return value headers, headerCount, pData, dataLength, resultCode and
-// szResultDescr are all valid.
-// In the return value pData[dataLength] == 0 always, as an extra safeguard
-// against programming slips.
-// Note that the function can succeed (ie not return NULL) yet result in an HTTP
-// error code. You should check that resultCode == 2xx before proceeding.
-// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above
-// list of functions
-
-EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_HttpTransaction(HNETLIBUSER hNlu, NETLIBHTTPREQUEST *pRequest);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Send data over a connection
-//
-// Returns the number of bytes sent on success, SOCKET_ERROR on failure
-// Errors: ERROR_INVALID_PARAMETER
-// anything from send(), nlu.pfnHttpGatewayWrapSend()
-// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
-// anything from socket(), connect(),
-// MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS
-// flags:
-
-#define MSG_NOHTTPGATEWAYWRAP 0x010000 // don't wrap the outgoing packet using nlu.pfnHttpGatewayWrapSend
-#define MSG_NODUMP 0x020000 // don't dump this packet to the log
-#define MSG_DUMPPROXY 0x040000 // this is proxy communiciation. For dump filtering only.
-#define MSG_DUMPASTEXT 0x080000 // this is textual data, don't dump as hex
-#define MSG_RAW 0x100000 // send as raw data, bypass any HTTP proxy stuff
-#define MSG_DUMPSSL 0x200000 // this is SSL traffic. For dump filtering only.
-#define MSG_NOTITLE 0x400000 // skip date, time & protocol from dump
-
-EXTERN_C MIR_APP_DLL(int) Netlib_Send(HNETLIBCONN hConn, const char *buf, int len, int flags = 0);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Receive data over a connection
-//
-// Returns the number of bytes read on success, SOCKET_ERROR on failure,
-// 0 if the connection has been closed
-// Flags supported: MSG_PEEK, MSG_NODUMP, MSG_DUMPPROXY, MSG_NOHTTPGATEWAYWRAP,
-// MSG_DUMPASTEXT, MSG_RAW
-// On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are
-// batched and cached and stuff, using this flag is not a guarantee that it
-// will be obeyed, and if it is it may even be propogated to future calls
-// even if you don't specify it then. Because of this, the flag should be
-// considered an all-or-nothing thing: either use it for the entire duration
-// of a connection, or not at all.
-// Errors: ERROR_INVALID_PARAMETER, anything from recv()
-// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
-// ERROR_INVALID_DATA (no Content-Length header in reply)
-// ERROR_NOT_ENOUGH_MEMORY (Content-Length very large)
-// ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved)
-// anything from select(), MS_NETLIB_RECVHTTPHEADERS,
-// nlu.pfnHttpGatewayUnwrapRecv, socket(), connect(),
-// MS_NETLIB_SENDHTTPREQUEST
-
-EXTERN_C MIR_APP_DLL(int) Netlib_Recv(HNETLIBCONN hConn, char *buf, int len, int flags = 0);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Determine the status of one or more connections
-// Returns the number of ready connections, SOCKET_ERROR on failure, 0 if the timeout expired.
-// All handles passed to this function must have been returned by either
-// MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT.
-// The last handle in each list must be followed by either NULL or INVALID_HANDLE_VALUE.
-// Errors: ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select()
-
-struct NETLIBSELECT
-{
- DWORD dwTimeout; // in milliseconds, INFINITE is acceptable
- HNETLIBCONN hReadConns[FD_SETSIZE + 1];
- HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
- HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_Select(NETLIBSELECT *nls);
-
-struct NETLIBSELECTEX
-{
- DWORD dwTimeout; // in milliseconds, INFINITE is acceptable
- HNETLIBCONN hReadConns[FD_SETSIZE + 1];
- HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
- HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
-
- BOOL hReadStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
- BOOL hWriteStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
- BOOL hExceptStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SelectEx(NETLIBSELECTEX *nls);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Shutdown connection
-
-EXTERN_C MIR_APP_DLL(void) Netlib_Shutdown(HNETLIBCONN h);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Create a packet receiver
-//
-// Returns a HANDLE on success, NULL on failure
-// The packet receiver implements the common situation where you have variable
-// length packets coming in over a connection and you want to split them up
-// in order to handle them.
-// The major limitation is that the buffer is created in memory, so you can't
-// have arbitrarily large packets.
-// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
-
-EXTERN_C MIR_APP_DLL(HANDLE) Netlib_CreatePacketReceiver(HNETLIBCONN hConnection, int iMaxSize);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Get the next set of packets from a packet receiver
-//
-// Returns the total number of bytes available in the buffer, 0 if the
-// connection was closed, SOCKET_ERROR on error.
-// hPacketRecver must have been returned by MS_NETLIB_CREATEPACKETRECVER
-// If nlpr.bytesUsed is set to zero and the buffer is already full up to
-// maxPacketSize, it is assumed that too large a packet has been received. All
-// data in the buffer is discarded and receiving is begun anew. This will
-// probably cause alignment problems so if you think this is likely to happen
-// then you should deal with it yourself.
-// Closing the packet receiver will not close the associated connection, but
-// will discard any bytes still in the buffer, so if you intend to carry on
-// reading from that connection, make sure you have processed the buffer first.
-// This function is the equivalent of a memmove() to remove the first bytesUsed
-// from the buffer, select() if dwTimeout is not INFINITE, then MS_NETLIB_RECV.
-// Errors: ERROR_INVALID_PARAMETER, ERROR_TIMEOUT,
-// anything from select(), MS_NETLIB_RECV
-
-struct NETLIBPACKETRECVER
-{
- DWORD dwTimeout; // fill before calling. In milliseconds. INFINITE is valid
- int bytesUsed; // fill before calling. This many bytes are removed from the start of the buffer. Set to 0 on return
- int bytesAvailable; // equal to the return value, unless the return value is 0
- int bufferSize; // same as parameter to MS_NETLIB_CREATEPACKETRECVER
- BYTE *buffer; // contains the recved data
-};
-
-EXTERN_C MIR_APP_DLL(int) Netlib_GetMorePackets(HANDLE hReceiver, NETLIBPACKETRECVER *nlprParam);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Sets a gateway polling timeout interval
-//
-// Returns previous timeout value
-// Errors: -1
-
-EXTERN_C MIR_APP_DLL(int) Netlib_SetPollingTimeout(HNETLIBCONN hConnection, int iTimeout);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// netlib log funcitons
-
-EXTERN_C MIR_APP_DLL(int) Netlib_Log(HNETLIBUSER hUser, const char *pszStr);
-EXTERN_C MIR_APP_DLL(int) Netlib_LogW(HNETLIBUSER hUser, const wchar_t *pwszStr);
-
-EXTERN_C MIR_APP_DLL(int) Netlib_Logf(HNETLIBUSER hUser, _Printf_format_string_ const char *fmt, ...);
-EXTERN_C MIR_APP_DLL(int) Netlib_LogfW(HNETLIBUSER hUser, _Printf_format_string_ const wchar_t *fmt, ...);
-
-EXTERN_C MIR_APP_DLL(void) Netlib_Dump(HNETLIBCONN nlc, const void *buf, size_t len, bool bIsSent, int flags);
-
-// Inits a required security provider. Right now only NTLM is supported
-// Returns HANDLE = NULL on error or non-null value on success
-// Known providers: Basic, NTLM, Negotiate, Kerberos, GSSAPI - (Kerberos SASL)
-EXTERN_C MIR_APP_DLL(HANDLE) Netlib_InitSecurityProvider(const wchar_t *szProviderName, const wchar_t *szPrincipal = nullptr);
-
-// Destroys a security provider's handle, provided by Netlib_InitSecurityProvider.
-// Right now only NTLM is supported
-EXTERN_C MIR_APP_DLL(void) Netlib_DestroySecurityProvider(HANDLE hProvider);
-
-// Returns the NTLM response string. The result value should be freed using mir_free
-EXTERN_C MIR_APP_DLL(char*) Netlib_NtlmCreateResponse(HANDLE hProvider, const char *szChallenge, wchar_t *szLogin, wchar_t *szPass, unsigned &complete);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// SSL/TLS support
-
-#if !defined(HSSL_DEFINED)
-DECLARE_HANDLE(HSSL);
-#endif
-
-// Makes connection SSL
-// Returns 0 on failure 1 on success
-EXTERN_C MIR_APP_DLL(int) Netlib_StartSsl(HNETLIBCONN hConnection, const char *host);
-
-// negotiates SSL session, verifies cert, returns NULL if failed
-EXTERN_C MIR_APP_DLL(HSSL) Netlib_SslConnect(SOCKET s, const char* host, int verify);
-
-// return true if there is either unsend or buffered received data (ie. after peek)
-EXTERN_C MIR_APP_DLL(BOOL) Netlib_SslPending(HSSL ssl);
-
-// reads number of bytes, keeps in buffer if peek != 0
-EXTERN_C MIR_APP_DLL(int) Netlib_SslRead(HSSL ssl, char *buf, int num, int peek);
-
-// writes data to the SSL socket
-EXTERN_C MIR_APP_DLL(int) Netlib_SslWrite(HSSL ssl, const char *buf, int num);
-
-// closes SSL session, but keeps socket open
-EXTERN_C MIR_APP_DLL(void) Netlib_SslShutdown(HSSL ssl);
-
-// frees all data associated with the SSL socket
-EXTERN_C MIR_APP_DLL(void) Netlib_SslFree(HSSL ssl);
-
-// gets TLS channel binging data for a socket
-EXTERN_C MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// WebSocket support
-
-struct WSHeader
-{
- WSHeader()
- {
- memset(this, 0, sizeof(*this));
- }
-
- bool bIsFinal, bIsMasked;
- int opCode, firstByte;
- size_t payloadSize, headerSize;
-};
-
-// connects to a WebSocket server
-EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
-
-// validates that the provided buffer contains full WebSocket datagram
-EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize);
-
-// sends a packet to WebSocket
-EXTERN_C MIR_APP_DLL(void) WebSocket_SendText(HNETLIBCONN nlc, const char *pData);
-EXTERN_C MIR_APP_DLL(void) WebSocket_SendBinary(HNETLIBCONN nlc, const void *pData, size_t strLen);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Netlib hooks (0.8+)
-
-// WARNING: these hooks are being called in the context of the calling thread, without switching
-// to the first thread, like all another events do. The hook procedure should be ready for the
-// multithreaded mode
-//
-// Parameters:
-// wParam: NETLIBNOTIFY* - points to the data being sent/received
-// lParam: NETLIBUSER* - points to the protocol definition
-
-struct NETLIBNOTIFY
-{
- const char *buf;
- int len;
- int flags;
- int result; // amount of bytes really sent/received
-};
-
-#define ME_NETLIB_FASTRECV "Netlib/OnRecv" // being called on every receive
-#define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send
-#define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump
-
-struct NETLIBCONNECTIONEVENTINFO
-{
- BOOL connected; // 1-opening socket 0-closing socket
- BOOL listening; // 1-bind 0-connect
- SOCKADDR_IN local; // local IP+port (always used)
- SOCKADDR_IN remote; // remote IP+port (only connect (opening + closing only if no proxy))
- SOCKADDR_IN proxy; // proxy IP+port (only connect when used)
- char *szSettingsModule; // name of the registered Netlib user that requested the action
-};
-
-//This event is sent as a new port is bound or a new connection opened.
-//It is NOT sent for sigle HTTP(S) requests.
-//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
-//lParam=(LPARAM)0 (not used)
-#define ME_NETLIB_EVENT_CONNECTED "Netlib/Event/Connected"
-
-//This event is sent if coneection or listening socket is closed.
-//It is NOT sent for sigle HTTP(S) requests.
-//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
-//lParam=(LPARAM)0 (not used)
-#define ME_NETLIB_EVENT_DISCONNECTED "Netlib/Event/Disconnected"
-
-#endif // M_NETLIB_H__
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-21 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-12 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_NETLIB_H__
+#define M_NETLIB_H__ 1
+
+#include "m_utils.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// this module was created in 0.1.2.2
+// All error codes are returned via GetLastError() (or WSAGetLastError():
+// they're the same).
+// This module is thread-safe where it is sensible for it to be so. This
+// basically means that you can call anything from any thread, but don't try
+// to predict what will happen if you try to recv() on the same connection from
+// two different threads at the same time.
+// Note that because the vast majority of the routines in this module return
+// a pointer, I have decided to diverge from the rest of Miranda and go with
+// the convention that functions return false on failure and nonzero on success.
+
+struct NETLIBHTTPREQUEST;
+struct NETLIBOPENCONNECTION;
+
+#define NETLIB_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.112 Safari/537.36"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Initialises the netlib for a set of connections
+// Returns a HNETLIBUSER to be used for future netlib calls, NULL on failure
+// NOTE: Netlib is loaded after any plugins, so you need to wait until
+// ME_SYSTEM_MODULESLOADED before calling this function
+// Netlib settings are stored under the module szSettingsModule
+// All netlib settings being with "NL".
+// The default settings for registered users that don't have any settings stored
+// in the database are the same as those displayed by the <All connections> page
+// of the netlib options page.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME
+
+struct NETLIBUSER
+{
+ char *szSettingsModule; // used for db settings and log
+ MAllStrings szDescriptiveName; // used in options dialog, already translated
+ DWORD flags;
+ int minIncomingPorts; // only if NUF_INCOMING. Will be used for validation of user input.
+};
+
+#define NUF_INCOMING 0x01 // binds incoming ports
+#define NUF_OUTGOING 0x02 // makes outgoing plain connections
+#define NUF_NOOPTIONS 0x08 // don't create an options page for this. szDescriptiveName is never used.
+#define NUF_HTTPCONNS 0x10 // at least some connections are made for HTTP communication. Enables the HTTP proxy option in options.
+#define NUF_NOHTTPSOPTION 0x20 // disable the HTTPS proxy option in options. Use this if all communication is HTTP.
+#define NUF_UNICODE 0x40 // if set ptszDescriptiveName points to Unicode, otherwise it points to ANSI string
+
+EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_RegisterUser(const NETLIBUSER *pDescr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Assign a Netlib user handle a set of dynamic HTTP headers to be used with all
+//
+// HTTP connections that enable the HTTP-use-sticky headers flag.
+// The headers persist until cleared with lParam = NULL.
+//
+// All memory should be allocated by the caller using malloc() from MS_SYSTEM_GET_MMI
+// Once it has passed to Netlib, Netlib is the owner of it, the caller should not refer to the memory
+// In any way after this point.
+//
+// NOTE: The szHeaders parameter should be a NULL terminated string following the HTTP header syntax.
+// This string will be injected verbatim, thus the user should be aware of setting strings that are not
+// headers. This service is NOT THREAD SAFE, only a single thread is expected to set the headers and a single
+// thread reading the pointer internally, stopping race conditions and mutual exclusion don't happen.
+//
+// Version 0.3.2a+ (2003/10/27)
+//
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetStickyHeaders(HNETLIBUSER nlu, const char *szHeaders);
+
+/* Notes on HTTP gateway usage
+When a connection is initiated through an HTTP proxy using
+MS_NETLIB_OPENCONNECTION, netlib will GET nlu.szHttpGatewayHello and read
+the replied headers. Once this succeeds nlu.pfnHttpGatewayInit will be called
+with a valid handle to the connection, the NETLIBOPENCONNECTION structure that
+MS_NETLIB_OPENCONNECTION was called with, and the replied HTTP headers as its
+parameters. This function is responsible for recving and parsing the data then
+calling MS_NETLIB_SETHTTPPROXYINFO with the appropriate information.
+nlu.pfnHttpGatewayInit should return nonzero on success. If it returns zero
+then the entire connection attempt will return signalling failure. If your
+function needs to return an error code it can do so via SetLastError().
+If nlu.pfnHttpGatewayInit returns success without having called
+MS_NETLIB_SETHTTPPROXYINFO then the connection attempt will fail anyway.
+If you need more fine-tuned control over the GET/POST URLs than just appending
+sequence numbers you can call MS_NETLIB_SETHTTPPROXYINFO from within your
+wrap/unwrap functions (see below).
+
+Just prior to MS_NETLIB_OPENCONNECTION returning nlu.pfnHttpGatewayBegin is
+called with the handle to the connection and the NETLIBOPENCONNECTION structure
+as its parameters. This is for gateways that need special non-protocol
+initialisation. If you do send any packets in this function, you probably want
+to remember to use the MSG_NOHTTPGATEWAYWRAP flag. This function pointer can be
+NULL if this functionality isn't needed. This function must return nonzero on
+success. If it fails the connect attempt will return failure without changing
+LastError.
+
+Whenever MS_NETLIB_SEND is called on a connection through an HTTP proxy and
+the MSG_NOHTTPGATEWAYWRAP flags is not set and nlu.pfnHttpGatewayWrapSend is
+not NULL, nlu.pfnHttpGatewayWrapSend will be called *instead* of sending the
+data. It is this function's responsibility to wrap the sending data
+appropriately for transmission and call pfnNetlibSend to send it again.
+The flags parameter to nlu.pfnHttpGatewayWrapSend should be passed straight
+through to the pfnNetlibSend call. It has already been ORed with
+MSG_NOHTTPGATEWAYWRAP. nlu.pfnHttpGatewayWrapSend should return the a
+number of the same type as MS_NETLIB_SEND, ie the number of bytes sent or
+SOCKET_ERROR. The number of wrapping bytes should be subtracted so that the
+return value appears as if the proxy wasn't there.
+pfnNetlibSend() is identical to CallService(MS_NETLIB_SEND, ...) but it's
+quicker to call using this pointer than to do the CallService() lookup again.
+
+Whenever an HTTP reply is received inside MS_NETLIB_RECV the headers and data
+are read into memory. If the headers indicate success then the data is passed
+to nlu.pfnHttpGatewayUnwrapRecv (if it's non-NULL) for processing. This
+function should remove (and do other processing if necessary) all HTTP proxy
+specific headers and return a pointer to the buffer whose size is returned in
+*outBufLen. If the buffer needs to be resized then NetlibRealloc() should be
+used for that purpose, *not* your own CRT's realloc(). NetlibRealloc() behaves
+identically to realloc() so it's possible to free the original buffer and
+create a new one if that's the most sensible way to write your parser.
+If errors are encountered you should SetLastError() and return NULL;
+MS_NETLIB_RECV will return SOCKET_ERROR. If the passed buffer unwraps to
+contain no actual data you should set *outBufLen to 0 but make sure you return
+some non-NULL buffer that can be freed.
+
+When you call MS_NETLIB_SEND or MS_NETLIB_RECV from any of these functions, you
+should use the MSG_DUMPPROXY flag so that the logging is neat.
+*/
+
+#define PROXYTYPE_SOCKS4 1
+#define PROXYTYPE_SOCKS5 2
+#define PROXYTYPE_HTTP 3
+#define PROXYTYPE_HTTPS 4
+#define PROXYTYPE_IE 5
+
+struct NETLIBUSERSETTINGS
+{
+ int cbSize; // to be filled in before calling
+ int useProxy; // 1 or 0
+ int proxyType; // a PROXYTYPE_
+ char *szProxyServer; // can be NULL
+ int wProxyPort; // host byte order
+ int useProxyAuth; // 1 or 0. Always 0 for SOCKS4
+ char *szProxyAuthUser; // can be NULL, always used by SOCKS4
+ char *szProxyAuthPassword; // can be NULL
+ int useProxyAuthNtlm; // 1 or 0, only used by HTTP, HTTPS
+ int dnsThroughProxy; // 1 or 0
+ int specifyIncomingPorts; // 1 or 0
+ char *szIncomingPorts; // can be NULL. Of form "1024-1050, 1060-1070, 2000"
+ int specifyOutgoingPorts; // 0.3.3a+
+ char *szOutgoingPorts; // 0.3.3a+
+ int enableUPnP; // 0.6.1+ only for NUF_INCOMING
+ int validateSSL;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the user-configured settings for a netlib user
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// The pointers referred to in the returned struct will remain valid until
+// the hUser handle is closed, or until the user changes the settings in the
+// options page, so it's best not to rely on them for too long.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//Gets the user-configured settings for a netlib user idetified by name
+//
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function behaves like Netlib_GetUserSettings but the user is identified
+//by the name provided by registration. When the name is not found NETLIBUSERSETTINGS is set to NULL.
+//Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Changes the user-configurable settings for a netlib user
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function is only really useful for people that specify NUF_NOOPTIONS
+// and want to create their own options.
+// Even if a setting is not active (eg szProxyAuthPassword when useProxyAuth is
+// zero) that settings is still set for use in the options dialog.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//Changes the user-configurable settings for a netlib user idetified by name
+//
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function behaves like Netlib_SetUserSettings but the user is identified
+//by the name provided by registration. Nothing will be changed when the name is not found.
+//Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Closes a netlib handle
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function should be called on all handles returned by netlib functions
+// once you are done with them. If it's called on a socket-type handle, the
+// socket will be closed.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE h);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Open a port and wait for connections on it
+//
+// Returns a HANDLE on success, NULL on failure
+// hUser should have been returned by MS_NETLIB_REGISTERUSER
+// This function does the equivalent of socket(), bind(), getsockname(),
+// listen(), accept()
+// Internally this function creates a new thread which waits around in accept()
+// for new connections. When one is received it calls nlb.pfnNewConnection *from
+// this new thread* and then loops back to wait again.
+// Close the returned handle to end the thread and close the open port.
+// Errors: ERROR_INVALID_PARAMETER, any returned by socket() or bind() or
+// listen() or getsockname()
+//
+// Notes:
+//
+// During development of 0.3.1a+ (2003/07/04) passing wPort != 0
+// will result in an attempt to bind on the port given in wPort
+// if this port is taken then you will get an error, so be sure to check
+// for such conditions.
+//
+// passing wPort != 0 is for people who need to open a set port for
+// daemon activities, usually passing wPort == 0 is what you want and
+// will result in a free port given by the TCP/IP socket layer and/or
+// seeded from the user selected port ranges.
+//
+// also note that wPort if != 0, will have be converted to network byte order
+//
+/* pExtra was added during 0.3.4+, prior its just two args, since we use the cdecl convention
+it shouldnt matter */
+
+typedef void (*NETLIBNEWCONNECTIONPROC)(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra);
+
+struct NETLIBBIND
+{
+ NETLIBNEWCONNECTIONPROC pfnNewConnection;
+
+ // function to call when there's a new connection. Params are: the
+ // new connection, IP of remote machine (host byte order)
+ DWORD dwInternalIP; // set on return, host byte order
+ DWORD dwExternalIP; // set on return, host byte order
+ WORD wPort, wExPort; // set on return, host byte order
+ void *pExtra; // argument is sent to callback
+};
+
+EXTERN_C MIR_APP_DLL(HNETLIBBIND) Netlib_BindPort(HNETLIBUSER nlu, NETLIBBIND *nlb);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Open a connection
+//
+// Returns a HNETLIBCONN to the new connection on success, NULL on failure
+// hUser must have been returned by MS_NETLIB_REGISTERUSER
+// Internally this function is the equivalent of socket(), gethostbyname(),
+// connect()
+// If NLOCF_HTTP is set and hUser is configured for an HTTP or HTTPS proxy then
+// this function will connect() to the proxy server only, without performing any
+// initialisation conversation.
+// If hUser is configured for an HTTP proxy and does not support HTTP gateways
+// and you try to open a connection without specifying NLOCF_HTTP then this
+// function will first attempt to open an HTTPS connection, if that fails it
+// will try a direct connection, if that fails it will return failure with the
+// error from the connect() during the direct connection attempt.
+// Errors: ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(),
+// connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select()
+// ERROR_TIMEOUT (during proxy communication)
+// ERROR_BAD_FORMAT (very invalid proxy reply)
+// ERROR_ACCESS_DENIED (by proxy)
+// ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd)
+// ERROR_INVALID_ACCESS (proxy refused identd auth)
+// ERROR_INVALID_DATA (proxy returned invalid code)
+// ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported)
+// ERROR_GEN_FAILURE (socks5/https general failure)
+// ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported)
+// ERROR_INVALID_ADDRESS (socks5 address type not supported)
+// HTTP: anything from nlu.pfnHttpGatewayInit, nlu.pfnHttpGatewayBegin,
+// MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS
+
+#define NLOCF_HTTP 0x0001 // this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy.
+#define NLOCF_STICKYHEADERS 0x0002 // this connection should send the sticky headers associated with NetLib user apart of any HTTP request
+#define NLOCF_V2 0x0004 // this connection understands the newer structure, newer cbSize isnt enough
+#define NLOCF_UDP 0x0008 // this connection is UDP
+#define NLOCF_SSL 0x0010 // this connection is SSL
+
+struct NETLIBOPENCONNECTION
+{
+ const char *szHost; // can contain the string representation of an IP
+ WORD wPort; // host byte order
+ DWORD flags;
+ unsigned int timeout;
+ /* optional, called in the context of the thread that issued the attempt, if it returns 0 the connection attempt is
+ stopped, the remaining timeout value can also be adjusted */
+ int (*waitcallback) (unsigned int *timeout);
+};
+
+EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const NETLIBOPENCONNECTION *nloc);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Sets the required information for an HTTP proxy connection
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function is designed to be called from within pfnHttpGatewayInit
+// See notes below MS_NETLIB_REGISTERUSER.
+// Errors: ERROR_INVALID_PARAMETER
+
+#define NLHPIF_USEGETSEQUENCE 0x0001 // append sequence numbers to GET requests
+#define NLHPIF_USEPOSTSEQUENCE 0x0002 // append sequence numbers to POST requests
+#define NLHPIF_GETPOSTSAMESEQUENCE 0x0004 // GET and POST use the same sequence
+#define NLHPIF_HTTP11 0x0008 // HTTP 1.1 proxy
+
+struct NETLIBHTTPPROXYINFO
+{
+ DWORD flags;
+ int firstGetSequence, firstPostSequence;
+ int combinePackets;
+ char *szHttpPostUrl;
+ char *szHttpGetUrl;
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetHttpProxyInfo(HNETLIBCONN hConnection, const NETLIBHTTPPROXYINFO *nlhpi);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the SOCKET associated with a netlib handle
+//
+// Returns the SOCKET on success, INVALID_SOCKET on failure
+// hNetlibHandle should have been returned by MS_NETLIB_BINDPORT or
+// MS_NETLIB_OPENCONNECTION only.
+// Be careful how you use this socket because you might be connected via an
+// HTTP proxy in which case calling send() or recv() will totally break things.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(UINT_PTR) Netlib_GetSocket(HNETLIBCONN hConnection);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define Netlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3)
+#define Netlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets HNETLIBUSER owner of a connection
+
+EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_GetConnNlu(HNETLIBCONN hConn);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the fake User-Agent header field to make some sites happy
+
+EXTERN_C MIR_APP_DLL(char*) Netlib_GetUserAgent();
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Converts numerical representation of IP in SOCKADDR_INET into string representation with IP and port
+// IPv4 will be supplied in formats address:port or address
+// IPv6 will be supplied in formats [address]:port or [address]
+// Returns pointer to the string or NULL if not successful
+
+struct sockaddr_in;
+EXTERN_C MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr);
+EXTERN_C MIR_APP_DLL(bool) Netlib_StringToAddress(const char *str, sockaddr_in *addr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets connection Information
+// IPv4 will be supplied in formats address:port or address
+// IPv6 will be supplied in formats [address]:port or [address]
+// Returns 0 if successful
+
+struct NETLIBCONNINFO
+{
+ char szIpPort[64];
+ unsigned dwIpv4;
+ WORD wPort;
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets connection Information
+//
+// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array
+// the last element of the array is all 0s, 0 if not successful
+
+struct NETLIBIPLIST
+{
+ unsigned cbNum;
+ char szIp[1][64];
+};
+
+EXTERN_C MIR_APP_DLL(NETLIBIPLIST*) Netlib_GetMyIp(bool bGlobalOnly);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Send an HTTP request over a connection
+//
+// Returns number of bytes sent on success, SOCKET_ERROR on failure
+// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+// Note that if you use NLHRF_SMARTAUTHHEADER and NTLM authentication is in use
+// then the full NTLM authentication transaction occurs, comprising sending the
+// domain, receiving the challenge, then sending the response.
+// nlhr.resultCode and nlhr.szResultDescr are ignored by this function.
+// Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND
+
+struct NETLIBHTTPHEADER
+{
+ char *szName;
+ char *szValue;
+};
+
+EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, const char *pszName);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define REQUEST_RESPONSE 0 // used by structure returned by MS_NETLIB_RECVHTTPHEADERS
+#define REQUEST_GET 1
+#define REQUEST_POST 2
+#define REQUEST_CONNECT 3
+#define REQUEST_HEAD 4
+#define REQUEST_PUT 5
+#define REQUEST_DELETE 6
+#define REQUEST_PATCH 7
+
+#define NLHRF_MANUALHOST 0x00000001 // do not remove any host and/or protocol portion of szUrl before sending it
+#define NLHRF_HTTP11 0x00000010 // use HTTP 1.1
+#define NLHRF_PERSISTENT 0x00000020 // preserve connection on exit, open connection provided in the nlc field of the reply
+ // it should be supplied in nlc field of request for reuse or closed if not needed
+#define NLHRF_SSL 0x00000040 // use SSL connection
+#define NLHRF_NOPROXY 0x00000080 // do not use proxy server
+#define NLHRF_REDIRECT 0x00000100 // handle HTTP redirect requests (response 30x), the resulting url provided in szUrl of the response
+#define NLHRF_NODUMP 0x00010000 // never dump this to the log
+#define NLHRF_NODUMPHEADERS 0x00020000 // don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION)
+#define NLHRF_DUMPPROXY 0x00040000 // this transaction is a proxy communication. For dump filtering only.
+#define NLHRF_DUMPASTEXT 0x00080000 // dump posted and reply data as text. Headers are always dumped as text.
+#define NLHRF_NODUMPSEND 0x00100000 // do not dump sent message.
+
+struct NETLIBHTTPREQUEST
+{
+ int cbSize;
+ int requestType; // a REQUEST_
+ DWORD flags;
+ char *szUrl;
+ NETLIBHTTPHEADER *headers; // If this is a POST request and headers
+ // doesn't contain a Content-Length it'll be added automatically
+ int headersCount;
+ char *pData; // data to be sent in POST request.
+ int dataLength; // must be 0 for REQUEST_GET/REQUEST_CONNECT
+ int resultCode;
+ char *szResultDescr;
+ HNETLIBCONN nlc;
+ int timeout;
+
+ __forceinline const char *operator[](const char *pszName) {
+ return Netlib_GetHeader(this, pszName);
+ }
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SendHttpRequest(HNETLIBCONN hConnection, NETLIBHTTPREQUEST *pRec);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Receives HTTP headers
+//
+// Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Call Netlib_FreeHttpRequest() to free this.
+// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+// nlhr->pData = NULL and nlhr->dataLength = 0 always. The requested data should
+// be retrieved using MS_NETLIB_RECV once the header has been parsed.
+// If the headers haven't finished within 60 seconds the function returns NULL
+// and ERROR_TIMEOUT.
+// Errors: ERROR_INVALID_PARAMETER, any from MS_NETLIB_RECV or select()
+// ERROR_HANDLE_EOF (connection closed before headers complete)
+// ERROR_TIMEOUT (headers still not complete after 60 seconds)
+// ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank)
+// ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long)
+// ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line)
+
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Free the memory used by a NETLIBHTTPREQUEST structure
+//
+// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This should only be called on structures returned by
+// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
+// arbitrary structure will have disastrous results.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST*);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// smart pointer for NETLIBHTTPREQUEST via a call of Netlib_FreeHttpRequest()
+
+#ifdef __cplusplus
+class NLHR_PTR
+{
+protected:
+ NETLIBHTTPREQUEST *_p;
+
+public:
+ __forceinline explicit NLHR_PTR(NETLIBHTTPREQUEST *p) : _p(p) {}
+
+ __forceinline NETLIBHTTPREQUEST* operator=(INT_PTR i_p)
+ {
+ return operator=((NETLIBHTTPREQUEST*)i_p);
+ }
+ __forceinline NETLIBHTTPREQUEST* operator=(NETLIBHTTPREQUEST *p)
+ {
+ if (_p)
+ Netlib_FreeHttpRequest(_p);
+ _p = p;
+ return _p;
+ }
+ __forceinline operator NETLIBHTTPREQUEST*() const { return _p; }
+ __forceinline NETLIBHTTPREQUEST* operator->() const { return _p; }
+ __forceinline ~NLHR_PTR()
+ {
+ Netlib_FreeHttpRequest(_p);
+ }
+};
+
+struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+{
+ MHttpRequest();
+ ~MHttpRequest();
+
+ CMStringA m_szUrl;
+ CMStringA m_szParam;
+ void *pUserInfo = nullptr;
+
+ void AddHeader(const char *szName, const char *szValue);
+};
+
+template <class T>
+class MTHttpRequest : public MHttpRequest
+{
+public:
+ __forceinline MTHttpRequest()
+ {}
+
+ typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
+ MTHttpRequestHandler m_pFunc = nullptr;
+};
+
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT64_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const CHAR_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Do an entire HTTP transaction
+//
+// Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Call Netlib_FreeHttpRequest() to free this.
+// hUser must have been returned by MS_NETLIB_REGISTERUSER
+// nlhr.szUrl should be a full HTTP URL. If it does not start with http:// , that
+// will be assumed (but it's best not to use this fact, for reasons of
+// extensibility).
+// This function is the equivalent of MS_NETLIB_OPENCONNECTION,
+// MS_NETLIB_SENDHTTPREQ, MS_NETLIB_RECVHTTPHEADERS, MS_NETLIB_RECV,
+// MS_NETLIB_CLOSEHANDLE
+// nlhr.headers will be augmented with the following headers unless they have
+// already been set by the caller:
+// "Host" (regardless of whether it is requested in nlhr.flags)
+// "User-Agent" (of the form "Miranda/0.1.2.2 (alpha)" or "Miranda/0.1.2.2")
+// "Content-Length" (for POSTs only. Set to nlhr.dataLength)
+// If you do not want to send one of these headers, create a nlhr.headers with
+// szValue = NULL.
+// In the return value headers, headerCount, pData, dataLength, resultCode and
+// szResultDescr are all valid.
+// In the return value pData[dataLength] == 0 always, as an extra safeguard
+// against programming slips.
+// Note that the function can succeed (ie not return NULL) yet result in an HTTP
+// error code. You should check that resultCode == 2xx before proceeding.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above
+// list of functions
+
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_HttpTransaction(HNETLIBUSER hNlu, NETLIBHTTPREQUEST *pRequest);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Send data over a connection
+//
+// Returns the number of bytes sent on success, SOCKET_ERROR on failure
+// Errors: ERROR_INVALID_PARAMETER
+// anything from send(), nlu.pfnHttpGatewayWrapSend()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// anything from socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS
+// flags:
+
+#define MSG_NOHTTPGATEWAYWRAP 0x010000 // don't wrap the outgoing packet using nlu.pfnHttpGatewayWrapSend
+#define MSG_NODUMP 0x020000 // don't dump this packet to the log
+#define MSG_DUMPPROXY 0x040000 // this is proxy communiciation. For dump filtering only.
+#define MSG_DUMPASTEXT 0x080000 // this is textual data, don't dump as hex
+#define MSG_RAW 0x100000 // send as raw data, bypass any HTTP proxy stuff
+#define MSG_DUMPSSL 0x200000 // this is SSL traffic. For dump filtering only.
+#define MSG_NOTITLE 0x400000 // skip date, time & protocol from dump
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Send(HNETLIBCONN hConn, const char *buf, int len, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Receive data over a connection
+//
+// Returns the number of bytes read on success, SOCKET_ERROR on failure,
+// 0 if the connection has been closed
+// Flags supported: MSG_PEEK, MSG_NODUMP, MSG_DUMPPROXY, MSG_NOHTTPGATEWAYWRAP,
+// MSG_DUMPASTEXT, MSG_RAW
+// On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are
+// batched and cached and stuff, using this flag is not a guarantee that it
+// will be obeyed, and if it is it may even be propogated to future calls
+// even if you don't specify it then. Because of this, the flag should be
+// considered an all-or-nothing thing: either use it for the entire duration
+// of a connection, or not at all.
+// Errors: ERROR_INVALID_PARAMETER, anything from recv()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// ERROR_INVALID_DATA (no Content-Length header in reply)
+// ERROR_NOT_ENOUGH_MEMORY (Content-Length very large)
+// ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved)
+// anything from select(), MS_NETLIB_RECVHTTPHEADERS,
+// nlu.pfnHttpGatewayUnwrapRecv, socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Recv(HNETLIBCONN hConn, char *buf, int len, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Determine the status of one or more connections
+// Returns the number of ready connections, SOCKET_ERROR on failure, 0 if the timeout expired.
+// All handles passed to this function must have been returned by either
+// MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT.
+// The last handle in each list must be followed by either NULL or INVALID_HANDLE_VALUE.
+// Errors: ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select()
+
+struct NETLIBSELECT
+{
+ DWORD dwTimeout; // in milliseconds, INFINITE is acceptable
+ HNETLIBCONN hReadConns[FD_SETSIZE + 1];
+ HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
+ HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Select(NETLIBSELECT *nls);
+
+struct NETLIBSELECTEX
+{
+ DWORD dwTimeout; // in milliseconds, INFINITE is acceptable
+ HNETLIBCONN hReadConns[FD_SETSIZE + 1];
+ HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
+ HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
+
+ BOOL hReadStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hWriteStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hExceptStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SelectEx(NETLIBSELECTEX *nls);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Shutdown connection
+
+EXTERN_C MIR_APP_DLL(void) Netlib_Shutdown(HNETLIBCONN h);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Create a packet receiver
+//
+// Returns a HANDLE on success, NULL on failure
+// The packet receiver implements the common situation where you have variable
+// length packets coming in over a connection and you want to split them up
+// in order to handle them.
+// The major limitation is that the buffer is created in memory, so you can't
+// have arbitrarily large packets.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
+
+EXTERN_C MIR_APP_DLL(HANDLE) Netlib_CreatePacketReceiver(HNETLIBCONN hConnection, int iMaxSize);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Get the next set of packets from a packet receiver
+//
+// Returns the total number of bytes available in the buffer, 0 if the
+// connection was closed, SOCKET_ERROR on error.
+// hPacketRecver must have been returned by MS_NETLIB_CREATEPACKETRECVER
+// If nlpr.bytesUsed is set to zero and the buffer is already full up to
+// maxPacketSize, it is assumed that too large a packet has been received. All
+// data in the buffer is discarded and receiving is begun anew. This will
+// probably cause alignment problems so if you think this is likely to happen
+// then you should deal with it yourself.
+// Closing the packet receiver will not close the associated connection, but
+// will discard any bytes still in the buffer, so if you intend to carry on
+// reading from that connection, make sure you have processed the buffer first.
+// This function is the equivalent of a memmove() to remove the first bytesUsed
+// from the buffer, select() if dwTimeout is not INFINITE, then MS_NETLIB_RECV.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_TIMEOUT,
+// anything from select(), MS_NETLIB_RECV
+
+struct NETLIBPACKETRECVER
+{
+ DWORD dwTimeout; // fill before calling. In milliseconds. INFINITE is valid
+ int bytesUsed; // fill before calling. This many bytes are removed from the start of the buffer. Set to 0 on return
+ int bytesAvailable; // equal to the return value, unless the return value is 0
+ int bufferSize; // same as parameter to MS_NETLIB_CREATEPACKETRECVER
+ BYTE *buffer; // contains the recved data
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetMorePackets(HANDLE hReceiver, NETLIBPACKETRECVER *nlprParam);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Sets a gateway polling timeout interval
+//
+// Returns previous timeout value
+// Errors: -1
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetPollingTimeout(HNETLIBCONN hConnection, int iTimeout);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// netlib log funcitons
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Log(HNETLIBUSER hUser, const char *pszStr);
+EXTERN_C MIR_APP_DLL(int) Netlib_LogW(HNETLIBUSER hUser, const wchar_t *pwszStr);
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Logf(HNETLIBUSER hUser, _Printf_format_string_ const char *fmt, ...);
+EXTERN_C MIR_APP_DLL(int) Netlib_LogfW(HNETLIBUSER hUser, _Printf_format_string_ const wchar_t *fmt, ...);
+
+EXTERN_C MIR_APP_DLL(void) Netlib_Dump(HNETLIBCONN nlc, const void *buf, size_t len, bool bIsSent, int flags);
+
+// Inits a required security provider. Right now only NTLM is supported
+// Returns HANDLE = NULL on error or non-null value on success
+// Known providers: Basic, NTLM, Negotiate, Kerberos, GSSAPI - (Kerberos SASL)
+EXTERN_C MIR_APP_DLL(HANDLE) Netlib_InitSecurityProvider(const wchar_t *szProviderName, const wchar_t *szPrincipal = nullptr);
+
+// Destroys a security provider's handle, provided by Netlib_InitSecurityProvider.
+// Right now only NTLM is supported
+EXTERN_C MIR_APP_DLL(void) Netlib_DestroySecurityProvider(HANDLE hProvider);
+
+// Returns the NTLM response string. The result value should be freed using mir_free
+EXTERN_C MIR_APP_DLL(char*) Netlib_NtlmCreateResponse(HANDLE hProvider, const char *szChallenge, wchar_t *szLogin, wchar_t *szPass, unsigned &complete);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SSL/TLS support
+
+#if !defined(HSSL_DEFINED)
+DECLARE_HANDLE(HSSL);
+#endif
+
+// Makes connection SSL
+// Returns 0 on failure 1 on success
+EXTERN_C MIR_APP_DLL(int) Netlib_StartSsl(HNETLIBCONN hConnection, const char *host);
+
+// negotiates SSL session, verifies cert, returns NULL if failed
+EXTERN_C MIR_APP_DLL(HSSL) Netlib_SslConnect(SOCKET s, const char* host, int verify);
+
+// return true if there is either unsend or buffered received data (ie. after peek)
+EXTERN_C MIR_APP_DLL(BOOL) Netlib_SslPending(HSSL ssl);
+
+// reads number of bytes, keeps in buffer if peek != 0
+EXTERN_C MIR_APP_DLL(int) Netlib_SslRead(HSSL ssl, char *buf, int num, int peek);
+
+// writes data to the SSL socket
+EXTERN_C MIR_APP_DLL(int) Netlib_SslWrite(HSSL ssl, const char *buf, int num);
+
+// closes SSL session, but keeps socket open
+EXTERN_C MIR_APP_DLL(void) Netlib_SslShutdown(HSSL ssl);
+
+// frees all data associated with the SSL socket
+EXTERN_C MIR_APP_DLL(void) Netlib_SslFree(HSSL ssl);
+
+// gets TLS channel binging data for a socket
+EXTERN_C MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// WebSocket support
+
+struct WSHeader
+{
+ WSHeader()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+
+ bool bIsFinal, bIsMasked;
+ int opCode, firstByte;
+ size_t payloadSize, headerSize;
+};
+
+// connects to a WebSocket server
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
+
+// validates that the provided buffer contains full WebSocket datagram
+EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize);
+
+// sends a packet to WebSocket
+EXTERN_C MIR_APP_DLL(void) WebSocket_SendText(HNETLIBCONN nlc, const char *pData);
+EXTERN_C MIR_APP_DLL(void) WebSocket_SendBinary(HNETLIBCONN nlc, const void *pData, size_t strLen);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Netlib hooks (0.8+)
+
+// WARNING: these hooks are being called in the context of the calling thread, without switching
+// to the first thread, like all another events do. The hook procedure should be ready for the
+// multithreaded mode
+//
+// Parameters:
+// wParam: NETLIBNOTIFY* - points to the data being sent/received
+// lParam: NETLIBUSER* - points to the protocol definition
+
+struct NETLIBNOTIFY
+{
+ const char *buf;
+ int len;
+ int flags;
+ int result; // amount of bytes really sent/received
+};
+
+#define ME_NETLIB_FASTRECV "Netlib/OnRecv" // being called on every receive
+#define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send
+#define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump
+
+struct NETLIBCONNECTIONEVENTINFO
+{
+ BOOL connected; // 1-opening socket 0-closing socket
+ BOOL listening; // 1-bind 0-connect
+ SOCKADDR_IN local; // local IP+port (always used)
+ SOCKADDR_IN remote; // remote IP+port (only connect (opening + closing only if no proxy))
+ SOCKADDR_IN proxy; // proxy IP+port (only connect when used)
+ char *szSettingsModule; // name of the registered Netlib user that requested the action
+};
+
+//This event is sent as a new port is bound or a new connection opened.
+//It is NOT sent for sigle HTTP(S) requests.
+//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
+//lParam=(LPARAM)0 (not used)
+#define ME_NETLIB_EVENT_CONNECTED "Netlib/Event/Connected"
+
+//This event is sent if coneection or listening socket is closed.
+//It is NOT sent for sigle HTTP(S) requests.
+//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
+//lParam=(LPARAM)0 (not used)
+#define ME_NETLIB_EVENT_DISCONNECTED "Netlib/Event/Disconnected"
+
+#endif // M_NETLIB_H__