android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / src / Net / WinINet / Request.cpp
blob42b9bc1a1c83f0ef8c6d3b985d99582f3cd21e75
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Net/Request.hpp"
25 #include "Net/Session.hpp"
26 #include "Util/ConvertString.hpp"
28 #include <assert.h>
29 #include <stdint.h>
31 static void CALLBACK
32 RequestCallback(HINTERNET hInternet,
33 DWORD_PTR dwContext,
34 DWORD dwInternetStatus,
35 LPVOID lpvStatusInformation,
36 DWORD dwStatusInformationLength)
38 Net::Request *request = (Net::Request *)dwContext;
40 request->Callback(dwInternetStatus,
41 lpvStatusInformation, dwStatusInformationLength);
44 Net::Request::Request(Session &session, const char *url,
45 unsigned timeout_ms)
47 UTF8ToWideConverter url2(url);
48 if (!url2.IsValid())
49 return;
51 INTERNET_STATUS_CALLBACK old_callback =
52 session.handle.SetStatusCallback(RequestCallback);
54 HINTERNET h = session.handle.OpenUrl(url2, NULL, 0,
55 INTERNET_FLAG_NO_AUTH |
56 INTERNET_FLAG_NO_AUTO_REDIRECT |
57 INTERNET_FLAG_NO_CACHE_WRITE |
58 INTERNET_FLAG_NO_COOKIES |
59 INTERNET_FLAG_NO_UI,
60 (DWORD_PTR)this);
62 if (h == NULL && GetLastError() == ERROR_IO_PENDING)
63 // Wait until we get the Request handle
64 opened_event.Wait(timeout_ms);
66 session.handle.SetStatusCallback(old_callback);
69 bool
70 Net::Request::Send(unsigned timeout_ms)
72 if (!handle.IsDefined())
73 return false;
75 if (!completed_event.Wait(timeout_ms))
76 /* response timeout */
77 return false;
79 if (last_error != ERROR_SUCCESS)
80 /* I/O error */
81 return false;
83 unsigned status = handle.GetStatusCode();
84 if (status < 200 || status >= 300)
85 /* unsuccessful HTTP status */
86 return false;
88 return true;
91 int64_t
92 Net::Request::GetLength() const
94 assert(handle.IsDefined());
96 return handle.GetContentLength();
99 ssize_t
100 Net::Request::Read(void *buffer, size_t buffer_size, unsigned timeout_ms)
102 INTERNET_BUFFERSA InetBuff;
103 FillMemory(&InetBuff, sizeof(InetBuff), 0);
104 InetBuff.dwStructSize = sizeof(InetBuff);
105 InetBuff.lpvBuffer = buffer;
106 InetBuff.dwBufferLength = buffer_size - 1;
108 if (!handle.Read(&InetBuff, IRF_ASYNC, (DWORD_PTR)this))
109 /* error */
110 return -1;
112 ((uint8_t *)buffer)[InetBuff.dwBufferLength] = 0;
113 return InetBuff.dwBufferLength;
116 void
117 Net::Request::Callback(DWORD status, LPVOID info, DWORD info_length)
119 // Request handle
120 switch (status) {
121 case INTERNET_STATUS_HANDLE_CREATED: {
122 INTERNET_ASYNC_RESULT *res = (INTERNET_ASYNC_RESULT *)info;
123 handle.Set((HINTERNET)res->dwResult);
124 opened_event.Signal();
125 break;
127 case INTERNET_STATUS_REQUEST_COMPLETE: {
128 INTERNET_ASYNC_RESULT *res = (INTERNET_ASYNC_RESULT *)info;
129 last_error = res->dwError;
130 completed_event.Signal();
131 break;