1 /* 2 * Copyright 2008 Hans Leidekker for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #ifndef _WINE_WINHTTP_PRIVATE_H_ 20 #define _WINE_WINHTTP_PRIVATE_H_ 21 22 #include <wine/config.h> 23 24 #include <stdarg.h> 25 26 #define WIN32_NO_STATUS 27 #define _INC_WINDOWS 28 #define COM_NO_WINDOWS_H 29 30 #define COBJMACROS 31 #define NONAMELESSUNION 32 33 #include <windef.h> 34 #include <winbase.h> 35 #include <objbase.h> 36 #include <oleauto.h> 37 #include <winsock2.h> 38 #include <winhttp.h> 39 40 #include <wine/list.h> 41 #include <wine/unicode.h> 42 43 #ifdef HAVE_SYS_SOCKET_H 44 # include <sys/socket.h> 45 #endif 46 #ifdef HAVE_NETINET_IN_H 47 # include <netinet/in.h> 48 #endif 49 #ifdef HAVE_NETDB_H 50 # include <netdb.h> 51 #endif 52 #if defined(__MINGW32__) || defined (_MSC_VER) 53 # include <ws2tcpip.h> 54 #else 55 # define closesocket close 56 # define ioctlsocket ioctl 57 #endif 58 59 #include <sspi.h> 60 61 #include <wine/debug.h> 62 WINE_DEFAULT_DEBUG_CHANNEL(winhttp); 63 64 static const WCHAR getW[] = {'G','E','T',0}; 65 static const WCHAR postW[] = {'P','O','S','T',0}; 66 static const WCHAR headW[] = {'H','E','A','D',0}; 67 static const WCHAR slashW[] = {'/',0}; 68 static const WCHAR http1_0[] = {'H','T','T','P','/','1','.','0',0}; 69 static const WCHAR http1_1[] = {'H','T','T','P','/','1','.','1',0}; 70 static const WCHAR chunkedW[] = {'c','h','u','n','k','e','d',0}; 71 72 typedef struct _object_header_t object_header_t; 73 74 typedef struct 75 { 76 void (*destroy)( object_header_t * ); 77 BOOL (*query_option)( object_header_t *, DWORD, void *, DWORD * ); 78 BOOL (*set_option)( object_header_t *, DWORD, void *, DWORD ); 79 } object_vtbl_t; 80 81 struct _object_header_t 82 { 83 DWORD type; 84 HINTERNET handle; 85 const object_vtbl_t *vtbl; 86 DWORD flags; 87 DWORD disable_flags; 88 DWORD logon_policy; 89 DWORD redirect_policy; 90 DWORD error; 91 DWORD_PTR context; 92 LONG refs; 93 WINHTTP_STATUS_CALLBACK callback; 94 DWORD notify_mask; 95 struct list entry; 96 struct list children; 97 }; 98 99 typedef struct 100 { 101 struct list entry; 102 WCHAR *name; 103 struct list cookies; 104 } domain_t; 105 106 typedef struct 107 { 108 struct list entry; 109 WCHAR *name; 110 WCHAR *value; 111 WCHAR *path; 112 } cookie_t; 113 114 typedef struct { 115 struct list entry; 116 LONG ref; 117 WCHAR *hostname; 118 INTERNET_PORT port; 119 BOOL secure; 120 struct list connections; 121 } hostdata_t; 122 123 typedef struct 124 { 125 object_header_t hdr; 126 LPWSTR agent; 127 DWORD access; 128 int resolve_timeout; 129 int connect_timeout; 130 int send_timeout; 131 int recv_timeout; 132 LPWSTR proxy_server; 133 LPWSTR proxy_bypass; 134 LPWSTR proxy_username; 135 LPWSTR proxy_password; 136 struct list cookie_cache; 137 HANDLE unload_event; 138 CredHandle cred_handle; 139 BOOL cred_handle_initialized; 140 DWORD secure_protocols; 141 } session_t; 142 143 typedef struct 144 { 145 object_header_t hdr; 146 session_t *session; 147 LPWSTR hostname; /* final destination of the request */ 148 LPWSTR servername; /* name of the server we directly connect to */ 149 LPWSTR username; 150 LPWSTR password; 151 INTERNET_PORT hostport; 152 INTERNET_PORT serverport; 153 struct sockaddr_storage sockaddr; 154 BOOL resolved; 155 } connect_t; 156 157 typedef struct 158 { 159 struct list entry; 160 int socket; 161 struct sockaddr_storage sockaddr; 162 BOOL secure; /* SSL active on connection? */ 163 hostdata_t *host; 164 ULONGLONG keep_until; 165 CtxtHandle ssl_ctx; 166 SecPkgContext_StreamSizes ssl_sizes; 167 char *ssl_buf; 168 char *extra_buf; 169 size_t extra_len; 170 char *peek_msg; 171 char *peek_msg_mem; 172 size_t peek_len; 173 } netconn_t; 174 175 typedef struct 176 { 177 LPWSTR field; 178 LPWSTR value; 179 BOOL is_request; /* part of request headers? */ 180 } header_t; 181 182 enum auth_target 183 { 184 TARGET_INVALID = -1, 185 TARGET_SERVER, 186 TARGET_PROXY, 187 TARGET_MAX 188 }; 189 190 enum auth_scheme 191 { 192 SCHEME_INVALID = -1, 193 SCHEME_BASIC, 194 SCHEME_NTLM, 195 SCHEME_PASSPORT, 196 SCHEME_DIGEST, 197 SCHEME_NEGOTIATE, 198 SCHEME_MAX 199 }; 200 201 struct authinfo 202 { 203 enum auth_scheme scheme; 204 CredHandle cred; 205 CtxtHandle ctx; 206 TimeStamp exp; 207 ULONG attr; 208 ULONG max_token; 209 char *data; 210 unsigned int data_len; 211 BOOL finished; /* finished authenticating */ 212 }; 213 214 typedef struct 215 { 216 object_header_t hdr; 217 connect_t *connect; 218 LPWSTR verb; 219 LPWSTR path; 220 LPWSTR version; 221 LPWSTR raw_headers; 222 void *optional; 223 DWORD optional_len; 224 netconn_t *netconn; 225 DWORD security_flags; 226 int resolve_timeout; 227 int connect_timeout; 228 int send_timeout; 229 int recv_timeout; 230 LPWSTR status_text; 231 DWORD content_length; /* total number of bytes to be read */ 232 DWORD content_read; /* bytes read so far */ 233 BOOL read_chunked; /* are we reading in chunked mode? */ 234 BOOL read_chunked_eof; /* end of stream in chunked mode */ 235 BOOL read_chunked_size; /* chunk size remaining */ 236 DWORD read_pos; /* current read position in read_buf */ 237 DWORD read_size; /* valid data size in read_buf */ 238 char read_buf[8192]; /* buffer for already read but not returned data */ 239 header_t *headers; 240 DWORD num_headers; 241 WCHAR **accept_types; 242 DWORD num_accept_types; 243 struct authinfo *authinfo; 244 struct authinfo *proxy_authinfo; 245 HANDLE task_wait; 246 HANDLE task_cancel; 247 HANDLE task_thread; 248 struct list task_queue; 249 CRITICAL_SECTION task_cs; 250 struct 251 { 252 WCHAR *username; 253 WCHAR *password; 254 } creds[TARGET_MAX][SCHEME_MAX]; 255 } request_t; 256 257 typedef struct _task_header_t task_header_t; 258 259 struct _task_header_t 260 { 261 struct list entry; 262 request_t *request; 263 void (*proc)( task_header_t * ); 264 }; 265 266 typedef struct 267 { 268 task_header_t hdr; 269 LPWSTR headers; 270 DWORD headers_len; 271 LPVOID optional; 272 DWORD optional_len; 273 DWORD total_len; 274 DWORD_PTR context; 275 } send_request_t; 276 277 typedef struct 278 { 279 task_header_t hdr; 280 } receive_response_t; 281 282 typedef struct 283 { 284 task_header_t hdr; 285 LPDWORD available; 286 } query_data_t; 287 288 typedef struct 289 { 290 task_header_t hdr; 291 LPVOID buffer; 292 DWORD to_read; 293 LPDWORD read; 294 } read_data_t; 295 296 typedef struct 297 { 298 task_header_t hdr; 299 LPCVOID buffer; 300 DWORD to_write; 301 LPDWORD written; 302 } write_data_t; 303 304 object_header_t *addref_object( object_header_t * ) DECLSPEC_HIDDEN; 305 object_header_t *grab_object( HINTERNET ) DECLSPEC_HIDDEN; 306 void release_object( object_header_t * ) DECLSPEC_HIDDEN; 307 HINTERNET alloc_handle( object_header_t * ) DECLSPEC_HIDDEN; 308 BOOL free_handle( HINTERNET ) DECLSPEC_HIDDEN; 309 310 void set_last_error( DWORD ) DECLSPEC_HIDDEN; 311 DWORD get_last_error( void ) DECLSPEC_HIDDEN; 312 void send_callback( object_header_t *, DWORD, LPVOID, DWORD ) DECLSPEC_HIDDEN; 313 void close_connection( request_t * ) DECLSPEC_HIDDEN; 314 315 BOOL netconn_close( netconn_t * ) DECLSPEC_HIDDEN; 316 netconn_t *netconn_create( hostdata_t *, const struct sockaddr_storage *, int ) DECLSPEC_HIDDEN; 317 void netconn_unload( void ) DECLSPEC_HIDDEN; 318 ULONG netconn_query_data_available( netconn_t * ) DECLSPEC_HIDDEN; 319 BOOL netconn_recv( netconn_t *, void *, size_t, int, int * ) DECLSPEC_HIDDEN; 320 BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_storage *, int ) DECLSPEC_HIDDEN; 321 BOOL netconn_secure_connect( netconn_t *, WCHAR *, DWORD, CredHandle * ) DECLSPEC_HIDDEN; 322 BOOL netconn_send( netconn_t *, const void *, size_t, int * ) DECLSPEC_HIDDEN; 323 DWORD netconn_set_timeout( netconn_t *, BOOL, int ) DECLSPEC_HIDDEN; 324 BOOL netconn_is_alive( netconn_t * ) DECLSPEC_HIDDEN; 325 const void *netconn_get_certificate( netconn_t * ) DECLSPEC_HIDDEN; 326 int netconn_get_cipher_strength( netconn_t * ) DECLSPEC_HIDDEN; 327 328 BOOL set_cookies( request_t *, const WCHAR * ) DECLSPEC_HIDDEN; 329 BOOL add_cookie_headers( request_t * ) DECLSPEC_HIDDEN; 330 BOOL add_request_headers( request_t *, LPCWSTR, DWORD, DWORD ) DECLSPEC_HIDDEN; 331 void delete_domain( domain_t * ) DECLSPEC_HIDDEN; 332 BOOL set_server_for_hostname( connect_t *, LPCWSTR, INTERNET_PORT ) DECLSPEC_HIDDEN; 333 void destroy_authinfo( struct authinfo * ) DECLSPEC_HIDDEN; 334 335 void release_host( hostdata_t *host ) DECLSPEC_HIDDEN; 336 337 extern HRESULT WinHttpRequest_create( void ** ) DECLSPEC_HIDDEN; 338 void release_typelib( void ) DECLSPEC_HIDDEN; 339 340 static inline void* __WINE_ALLOC_SIZE(1) heap_alloc( SIZE_T size ) 341 { 342 return HeapAlloc( GetProcessHeap(), 0, size ); 343 } 344 345 static inline void* __WINE_ALLOC_SIZE(1) heap_alloc_zero( SIZE_T size ) 346 { 347 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); 348 } 349 350 static inline void* __WINE_ALLOC_SIZE(2) heap_realloc( LPVOID mem, SIZE_T size ) 351 { 352 return HeapReAlloc( GetProcessHeap(), 0, mem, size ); 353 } 354 355 static inline void* __WINE_ALLOC_SIZE(2) heap_realloc_zero( LPVOID mem, SIZE_T size ) 356 { 357 return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, size ); 358 } 359 360 static inline BOOL heap_free( LPVOID mem ) 361 { 362 return HeapFree( GetProcessHeap(), 0, mem ); 363 } 364 365 static inline WCHAR *strdupW( const WCHAR *src ) 366 { 367 WCHAR *dst; 368 369 if (!src) return NULL; 370 dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ); 371 if (dst) strcpyW( dst, src ); 372 return dst; 373 } 374 375 static inline WCHAR *strdupAW( const char *src ) 376 { 377 WCHAR *dst = NULL; 378 if (src) 379 { 380 DWORD len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 ); 381 if ((dst = heap_alloc( len * sizeof(WCHAR) ))) 382 MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len ); 383 } 384 return dst; 385 } 386 387 static inline char *strdupWA( const WCHAR *src ) 388 { 389 char *dst = NULL; 390 if (src) 391 { 392 int len = WideCharToMultiByte( CP_ACP, 0, src, -1, NULL, 0, NULL, NULL ); 393 if ((dst = heap_alloc( len ))) 394 WideCharToMultiByte( CP_ACP, 0, src, -1, dst, len, NULL, NULL ); 395 } 396 return dst; 397 } 398 399 static inline char *strdupWA_sized( const WCHAR *src, DWORD size ) 400 { 401 char *dst = NULL; 402 if (src) 403 { 404 int len = WideCharToMultiByte( CP_ACP, 0, src, size, NULL, 0, NULL, NULL ) + 1; 405 if ((dst = heap_alloc( len ))) 406 { 407 WideCharToMultiByte( CP_ACP, 0, src, len, dst, size, NULL, NULL ); 408 dst[len - 1] = 0; 409 } 410 } 411 return dst; 412 } 413 414 extern HINSTANCE winhttp_instance DECLSPEC_HIDDEN; 415 416 #endif /* _WINE_WINHTTP_PRIVATE_H_ */ 417