winhttp: Implement WinHttpOpenRequest.
[wine] / dlls / winhttp / session.c
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 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnls.h"
28 #include "winhttp.h"
29
30 #include "winhttp_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
33
34 static void set_last_error( DWORD error )
35 {
36     /* FIXME */
37     SetLastError( error );
38 }
39
40 /***********************************************************************
41  *          WinHttpCheckPlatform (winhttp.@)
42  */
43 BOOL WINAPI WinHttpCheckPlatform( void )
44 {
45     TRACE("\n");
46     return TRUE;
47 }
48
49 /***********************************************************************
50  *          session_destroy (internal)
51  */
52 static void session_destroy( object_header_t *hdr )
53 {
54     session_t *session = (session_t *)hdr;
55
56     TRACE("%p\n", session);
57
58     heap_free( session->agent );
59     heap_free( session->proxy_server );
60     heap_free( session->proxy_bypass );
61     heap_free( session->proxy_username );
62     heap_free( session->proxy_password );
63     heap_free( session );
64 }
65
66 static const object_vtbl_t session_vtbl =
67 {
68     session_destroy,
69     NULL,
70     NULL
71 };
72
73 /***********************************************************************
74  *          WinHttpOpen (winhttp.@)
75  */
76 HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags )
77 {
78     session_t *session;
79     HINTERNET handle = NULL;
80
81     TRACE("%s, %u, %s, %s, 0x%08x\n", debugstr_w(agent), access, debugstr_w(proxy), debugstr_w(bypass), flags);
82
83     if (!(session = heap_alloc_zero( sizeof(session_t) ))) return NULL;
84
85     session->hdr.type = WINHTTP_HANDLE_TYPE_SESSION;
86     session->hdr.vtbl = &session_vtbl;
87     session->hdr.flags = flags;
88     session->hdr.refs = 1;
89     session->access = access;
90
91     if (agent && !(session->agent = strdupW( agent ))) goto end;
92     if (proxy && !(session->proxy_server = strdupW( proxy ))) goto end;
93     if (bypass && !(session->proxy_bypass = strdupW( bypass ))) goto end;
94
95     if (!(handle = alloc_handle( &session->hdr ))) goto end;
96     session->hdr.handle = handle;
97
98 end:
99     release_object( &session->hdr );
100     TRACE("returning %p\n", handle);
101     return handle;
102 }
103
104 /***********************************************************************
105  *          connect_destroy (internal)
106  */
107 static void connect_destroy( object_header_t *hdr )
108 {
109     connect_t *connect = (connect_t *)hdr;
110
111     TRACE("%p\n", connect);
112
113     release_object( &connect->session->hdr );
114
115     heap_free( connect->hostname );
116     heap_free( connect->servername );
117     heap_free( connect->username );
118     heap_free( connect->password );
119     heap_free( connect );
120 }
121
122 static const object_vtbl_t connect_vtbl =
123 {
124     connect_destroy,
125     NULL,
126     NULL
127 };
128
129 /***********************************************************************
130  *          WinHttpConnect (winhttp.@)
131  */
132 HINTERNET WINAPI WinHttpConnect( HINTERNET hsession, LPCWSTR server, INTERNET_PORT port, DWORD reserved )
133 {
134     connect_t *connect;
135     session_t *session;
136     HINTERNET hconnect = NULL;
137
138     TRACE("%p, %s, %u, %x\n", hsession, debugstr_w(server), port, reserved);
139
140     if (!server)
141     {
142         set_last_error( ERROR_INVALID_PARAMETER );
143         return NULL;
144     }
145     if (!(session = (session_t *)grab_object( hsession )))
146     {
147         set_last_error( ERROR_INVALID_HANDLE );
148         return NULL;
149     }
150     if (session->hdr.type != WINHTTP_HANDLE_TYPE_SESSION)
151     {
152         release_object( &session->hdr );
153         set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
154         return NULL;
155     }
156     if (!(connect = heap_alloc_zero( sizeof(connect_t) )))
157     {
158         release_object( &session->hdr );
159         return NULL;
160     }
161     connect->hdr.type = WINHTTP_HANDLE_TYPE_CONNECT;
162     connect->hdr.vtbl = &connect_vtbl;
163     connect->hdr.refs = 1;
164     connect->hdr.flags = session->hdr.flags;
165     connect->hdr.callback = session->hdr.callback;
166     connect->hdr.notify_mask = session->hdr.notify_mask;
167
168     addref_object( &session->hdr );
169     connect->session = session;
170     list_add_head( &session->hdr.children, &connect->hdr.entry );
171
172     if (server && !(connect->hostname = strdupW( server ))) goto end;
173     connect->hostport = port;
174
175     if (!(hconnect = alloc_handle( &connect->hdr ))) goto end;
176     connect->hdr.handle = hconnect;
177
178 end:
179     release_object( &connect->hdr );
180
181     TRACE("returning %p\n", hconnect);
182     return hconnect;
183 }
184
185 /***********************************************************************
186  *          request_destroy (internal)
187  */
188 static void request_destroy( object_header_t *hdr )
189 {
190     request_t *request = (request_t *)hdr;
191     int i;
192
193     TRACE("%p\n", request);
194
195     release_object( &request->connect->hdr );
196
197     heap_free( request->verb );
198     heap_free( request->path );
199     heap_free( request->version );
200     heap_free( request->raw_headers );
201     heap_free( request->status_text );
202     for (i = 0; i < request->num_headers; i++)
203     {
204         heap_free( request->headers[i].field );
205         heap_free( request->headers[i].value );
206     }
207     heap_free( request->headers );
208     heap_free( request );
209 }
210
211 static const object_vtbl_t request_vtbl =
212 {
213     request_destroy,
214     NULL,
215     NULL
216 };
217
218 /***********************************************************************
219  *          WinHttpOpenRequest (winhttp.@)
220  */
221 HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR object, LPCWSTR version,
222                                      LPCWSTR referrer, LPCWSTR *types, DWORD flags )
223 {
224     request_t *request;
225     connect_t *connect;
226     HINTERNET hrequest = NULL;
227
228     TRACE("%p, %s, %s, %s, %s, %p, 0x%08x\n", hconnect, debugstr_w(verb), debugstr_w(object),
229           debugstr_w(version), debugstr_w(referrer), types, flags);
230
231     if (!(connect = (connect_t *)grab_object( hconnect )))
232     {
233         set_last_error( ERROR_INVALID_HANDLE );
234         return NULL;
235     }
236     if (connect->hdr.type != WINHTTP_HANDLE_TYPE_CONNECT)
237     {
238         release_object( &connect->hdr );
239         set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
240         return NULL;
241     }
242     if (!(request = heap_alloc_zero( sizeof(request_t) )))
243     {
244         release_object( &connect->hdr );
245         return NULL;
246     }
247     request->hdr.type = WINHTTP_HANDLE_TYPE_REQUEST;
248     request->hdr.vtbl = &request_vtbl;
249     request->hdr.refs = 1;
250     request->hdr.flags = flags;
251     request->hdr.callback = connect->hdr.callback;
252     request->hdr.notify_mask = connect->hdr.notify_mask;
253
254     addref_object( &connect->hdr );
255     request->connect = connect;
256     list_add_head( &connect->hdr.children, &request->hdr.entry );
257
258     if (verb && !(request->verb = strdupW( verb ))) goto end;
259     if (object && !(request->path = strdupW( object ))) goto end;
260     if (version && !(request->version = strdupW( version ))) goto end;
261
262     if (!(hrequest = alloc_handle( &request->hdr ))) goto end;
263     request->hdr.handle = hrequest;
264
265 end:
266     release_object( &request->hdr );
267
268     TRACE("returning %p\n", hrequest);
269     return hrequest;
270 }
271
272 /***********************************************************************
273  *          WinHttpCloseHandle (winhttp.@)
274  */
275 BOOL WINAPI WinHttpCloseHandle( HINTERNET handle )
276 {
277     object_header_t *hdr;
278
279     TRACE("%p\n", handle);
280
281     if (!(hdr = grab_object( handle )))
282     {
283         set_last_error( ERROR_INVALID_HANDLE );
284         return FALSE;
285     }
286     release_object( hdr );
287     free_handle( handle );
288     return TRUE;
289 }