Mon, 24 Mar 2014 19:56:42 +0100
Update libgadu yet again
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
1 | /* $Id$ */ |
| 11360 | 2 | |
| 3 | /* | |
| 4 | * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl> | |
| 5 | * | |
| 6 | * This program is free software; you can redistribute it and/or modify | |
| 7 | * it under the terms of the GNU Lesser General Public License Version | |
| 8 | * 2.1 as published by the Free Software Foundation. | |
| 9 | * | |
| 10 | * This program is distributed in the hope that it will be useful, | |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 13 | * GNU Lesser General Public License for more details. | |
| 14 | * | |
| 15 | * You should have received a copy of the GNU Lesser General Public | |
| 16 | * License along with this program; if not, write to the Free Software | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, |
| 11360 | 18 | * USA. |
| 19 | */ | |
| 20 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
21 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
22 | * \file http.c |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
23 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
24 | * \brief Obsługa połączeń HTTP |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
25 | */ |
|
29106
51c7b2177e42
Fix all the remaining files for which internal.h doesn't end up being the first include.
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
26 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
27 | #include "strman.h" |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
28 | #include "network.h" |
|
31826
0f6ab56fbf9d
Update libgadu to 0.11.0 plus local changes; thanks to Tomasz Wasilczyk.
Ethan Blanton <elb@pidgin.im>
parents:
31609
diff
changeset
|
29 | #include "libgadu.h" |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
30 | #include "resolver.h" |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
31 | #include "internal.h" |
| 11360 | 32 | |
| 33 | #include <ctype.h> | |
| 34 | #include <errno.h> | |
| 35 | #include <stdlib.h> | |
| 36 | #include <string.h> | |
| 37 | ||
|
35214
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
38 | #define GG_HTTP_MAX_LENGTH 1000000000 |
|
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
39 | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
40 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
41 | * Rozpoczyna połączenie HTTP. |
| 11360 | 42 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
43 | * Funkcja przeprowadza połączenie HTTP przy połączeniu synchronicznym, |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
44 | * zwracając wynik w polach struktury \c gg_http, lub błąd, gdy sesja się |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
45 | * nie powiedzie. |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
46 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
47 | * Przy połączeniu asynchronicznym, funkcja rozpoczyna połączenie, a dalsze |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
48 | * etapy będą przeprowadzane po wykryciu zmian (\c watch) na obserwowanym |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
49 | * deskryptorze (\c fd) i wywołaniu funkcji \c gg_http_watch_fd(). |
| 11360 | 50 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
51 | * Po zakończeniu, należy zwolnić strukturę za pomocą funkcji |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
52 | * \c gg_http_free(). Połączenie asynchroniczne można zatrzymać w każdej |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
53 | * chwili za pomocą \c gg_http_stop(). |
| 11360 | 54 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
55 | * \param hostname Adres serwera |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
56 | * \param port Port serwera |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
57 | * \param async Flaga asynchronicznego połączenia |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
58 | * \param method Metoda HTTP |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
59 | * \param path Ścieżka do zasobu (musi być poprzedzona znakiem '/') |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
60 | * \param header Nagłówek zapytania plus ewentualne dane dla POST |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
61 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
62 | * \return Zaalokowana struktura \c gg_http lub NULL, jeśli wystąpił błąd. |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
63 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
64 | * \ingroup http |
| 11360 | 65 | */ |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
66 | struct gg_http *gg_http_connect(const char *hostname, int port, int async, |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
67 | const char *method, const char *path, const char *header) |
| 11360 | 68 | { |
| 69 | struct gg_http *h; | |
| 70 | ||
| 71 | if (!hostname || !port || !method || !path || !header) { | |
| 72 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n"); | |
| 73 | errno = EFAULT; | |
| 74 | return NULL; | |
| 75 | } | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
76 | |
| 11360 | 77 | if (!(h = malloc(sizeof(*h)))) |
| 78 | return NULL; | |
| 79 | memset(h, 0, sizeof(*h)); | |
| 80 | ||
| 81 | h->async = async; | |
| 82 | h->port = port; | |
| 83 | h->fd = -1; | |
| 84 | h->type = GG_SESSION_HTTP; | |
| 85 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
86 | gg_http_set_resolver(h, GG_RESOLVER_DEFAULT); |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
87 | |
| 11360 | 88 | if (gg_proxy_enabled) { |
| 89 | char *auth = gg_proxy_auth(); | |
| 90 | ||
| 91 | h->query = gg_saprintf("%s http://%s:%d%s HTTP/1.0\r\n%s%s", | |
| 92 | method, hostname, port, path, (auth) ? auth : | |
| 93 | "", header); | |
| 94 | hostname = gg_proxy_host; | |
| 95 | h->port = port = gg_proxy_port; | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
96 | free(auth); |
| 11360 | 97 | |
| 98 | } else { | |
| 99 | h->query = gg_saprintf("%s %s HTTP/1.0\r\n%s", | |
| 100 | method, path, header); | |
| 101 | } | |
| 102 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
103 | if (h->query == NULL) { |
| 11360 | 104 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n"); |
| 105 | free(h); | |
| 106 | errno = ENOMEM; | |
| 107 | return NULL; | |
| 108 | } | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
109 | |
| 11360 | 110 | gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", h->query); |
| 111 | ||
| 112 | if (async) { | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
113 | if (h->resolver_start(&h->fd, &h->resolver, hostname) == -1) { |
| 11360 | 114 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n"); |
| 115 | gg_http_free(h); | |
| 116 | errno = ENOENT; | |
| 117 | return NULL; | |
| 118 | } | |
| 119 | ||
| 120 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver = %p\n", h->resolver); | |
| 121 | ||
| 122 | h->state = GG_STATE_RESOLVING; | |
| 123 | h->check = GG_CHECK_READ; | |
| 124 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 125 | } else { | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
126 | struct in_addr *addr_list = NULL; |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
127 | unsigned int addr_count; |
| 11360 | 128 | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
129 | if (gg_gethostbyname_real(hostname, &addr_list, &addr_count, 0) == -1 || addr_count == 0) { |
| 11360 | 130 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n"); |
| 131 | gg_http_free(h); | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
132 | free(addr_list); |
| 11360 | 133 | errno = ENOENT; |
| 134 | return NULL; | |
| 135 | } | |
| 136 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
137 | h->fd = gg_connect(&addr_list[0], port, 0); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
138 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
139 | if (h->fd == -1) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
140 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
141 | "connection failed (errno=%d, %s)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
142 | errno, strerror(errno)); |
| 11360 | 143 | gg_http_free(h); |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
144 | free(addr_list); |
| 11360 | 145 | return NULL; |
| 146 | } | |
| 147 | ||
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
148 | free(addr_list); |
|
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
149 | |
| 11360 | 150 | h->state = GG_STATE_CONNECTING; |
| 151 | ||
| 152 | while (h->state != GG_STATE_ERROR && h->state != GG_STATE_PARSING) { | |
| 153 | if (gg_http_watch_fd(h) == -1) | |
| 154 | break; | |
| 155 | } | |
| 156 | ||
| 157 | if (h->state != GG_STATE_PARSING) { | |
| 158 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n"); | |
| 159 | gg_http_free(h); | |
| 160 | return NULL; | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | h->callback = gg_http_watch_fd; | |
| 165 | h->destroy = gg_http_free; | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
166 | |
| 11360 | 167 | return h; |
| 168 | } | |
| 169 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
170 | #ifndef DOXYGEN |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
171 | |
| 11360 | 172 | #define gg_http_error(x) \ |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
173 | if (h->fd > -1) \ |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
174 | close(h->fd); \ |
| 11360 | 175 | h->fd = -1; \ |
| 176 | h->state = GG_STATE_ERROR; \ | |
| 177 | h->error = x; \ | |
| 178 | return 0; | |
| 179 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
180 | #endif /* DOXYGEN */ |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
181 | |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
182 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
183 | * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia. |
| 11360 | 184 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
185 | * Operacja będzie zakończona, gdy pole \c state będzie równe |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
186 | * \c GG_STATE_PARSING. W tym miejscu działanie przejmuje zwykle funkcja |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
187 | * korzystająca z \c gg_http_watch_fd(). W przypadku błędu połączenia, |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
188 | * pole \c state będzie równe \c GG_STATE_ERROR, a kod błędu znajdzie się |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
189 | * w polu \c error. |
| 11360 | 190 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
191 | * \param h Struktura połączenia |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
192 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
193 | * \return \return 0 jeśli się powiodło, -1 w przypadku błędu |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
194 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
195 | * \ingroup http |
| 11360 | 196 | */ |
| 197 | int gg_http_watch_fd(struct gg_http *h) | |
| 198 | { | |
| 199 | gg_debug(GG_DEBUG_FUNCTION, "** gg_http_watch_fd(%p);\n", h); | |
| 200 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
201 | if (h == NULL) { |
| 11360 | 202 | gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n"); |
| 203 | errno = EFAULT; | |
| 204 | return -1; | |
| 205 | } | |
| 206 | ||
| 207 | if (h->state == GG_STATE_RESOLVING) { | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
208 | struct in_addr addr; |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
209 | int res; |
| 11360 | 210 | |
| 211 | gg_debug(GG_DEBUG_MISC, "=> http, resolving done\n"); | |
| 212 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
213 | do { |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
214 | res = gg_resolver_recv(h->fd, &addr, sizeof(addr)); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
215 | } while (res == -1 && errno == EINTR); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
216 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
217 | h->resolver_cleanup(&h->resolver, 0); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
218 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
219 | if (res != sizeof(addr) || addr.s_addr == INADDR_NONE) { |
| 11360 | 220 | gg_debug(GG_DEBUG_MISC, "=> http, resolver thread failed\n"); |
| 221 | gg_http_error(GG_ERROR_RESOLVING); | |
| 222 | } | |
| 223 | ||
| 224 | close(h->fd); | |
| 225 | h->fd = -1; | |
| 226 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
227 | gg_debug(GG_DEBUG_MISC, "=> http, connecting to %s:%d\n", inet_ntoa(addr), h->port); |
| 11360 | 228 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
229 | h->fd = gg_connect(&addr, h->port, h->async); |
| 11360 | 230 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
231 | if (h->fd == -1) { |
| 11360 | 232 | gg_debug(GG_DEBUG_MISC, "=> http, connection failed (errno=%d, %s)\n", errno, strerror(errno)); |
| 233 | gg_http_error(GG_ERROR_CONNECTING); | |
| 234 | } | |
| 235 | ||
| 236 | h->state = GG_STATE_CONNECTING; | |
| 237 | h->check = GG_CHECK_WRITE; | |
| 238 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 239 | ||
| 240 | return 0; | |
| 241 | } | |
| 242 | ||
| 243 | if (h->state == GG_STATE_CONNECTING) { | |
| 244 | int res = 0; | |
|
29752
5cb6314b2477
Partially fix libgadu build on Win32. Refs #10542. I'm still not sure how to
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29751
diff
changeset
|
245 | socklen_t res_size = sizeof(res); |
| 11360 | 246 | |
| 247 | if (h->async && (getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
248 | gg_debug(GG_DEBUG_MISC, "=> http, async connection " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
249 | "failed (errno=%d, %s)\n", (res) ? res : errno, |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
250 | strerror((res) ? res : errno)); |
| 11360 | 251 | close(h->fd); |
| 252 | h->fd = -1; | |
| 253 | h->state = GG_STATE_ERROR; | |
| 254 | h->error = GG_ERROR_CONNECTING; | |
| 255 | if (res) | |
| 256 | errno = res; | |
| 257 | return 0; | |
| 258 | } | |
| 259 | ||
| 260 | gg_debug(GG_DEBUG_MISC, "=> http, connected, sending request\n"); | |
| 261 | ||
| 262 | h->state = GG_STATE_SENDING_QUERY; | |
| 263 | } | |
| 264 | ||
| 265 | if (h->state == GG_STATE_SENDING_QUERY) { | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
266 | int res; |
| 11360 | 267 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
268 | res = send(h->fd, h->query, strlen(h->query), 0); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
269 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
270 | if (res == -1 && errno != EINTR && errno != EAGAIN) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
271 | gg_debug(GG_DEBUG_MISC, "=> http, send() failed " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
272 | "(len=%" GG_SIZE_FMT ", res=%d, errno=%d)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
273 | strlen(h->query), res, errno); |
| 11360 | 274 | gg_http_error(GG_ERROR_WRITING); |
| 275 | } | |
| 276 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
277 | if (res == -1) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
278 | gg_debug(GG_DEBUG_MISC, "=> http, non-critical send " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
279 | "error (errno=%d, %s)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
280 | errno, strerror(errno)); |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
281 | return 0; |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
282 | } |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
283 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
284 | if ((size_t) res < strlen(h->query)) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
285 | gg_debug(GG_DEBUG_MISC, "=> http, partial header sent " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
286 | "(led=%" GG_SIZE_FMT ", sent=%d)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
287 | strlen(h->query), res); |
| 11360 | 288 | |
| 289 | memmove(h->query, h->query + res, strlen(h->query) - res + 1); | |
| 290 | h->state = GG_STATE_SENDING_QUERY; | |
| 291 | h->check = GG_CHECK_WRITE; | |
| 292 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 293 | } else { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
294 | gg_debug(GG_DEBUG_MISC, "=> http, request sent (len=%" |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
295 | GG_SIZE_FMT ")\n", strlen(h->query)); |
| 11360 | 296 | free(h->query); |
| 297 | h->query = NULL; | |
| 298 | ||
| 299 | h->state = GG_STATE_READING_HEADER; | |
| 300 | h->check = GG_CHECK_READ; | |
| 301 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 302 | } | |
| 303 | ||
| 304 | return 0; | |
| 305 | } | |
| 306 | ||
| 307 | if (h->state == GG_STATE_READING_HEADER) { | |
| 308 | char buf[1024], *tmp; | |
| 309 | int res; | |
| 310 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
311 | res = recv(h->fd, buf, sizeof(buf), 0); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
312 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
313 | if (res == -1 && errno != EINTR && errno != EAGAIN) { |
| 11360 | 314 | gg_debug(GG_DEBUG_MISC, "=> http, reading header failed (errno=%d)\n", errno); |
| 315 | if (h->header) { | |
| 316 | free(h->header); | |
| 317 | h->header = NULL; | |
| 318 | } | |
| 319 | gg_http_error(GG_ERROR_READING); | |
| 320 | } | |
| 321 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
322 | if (res == -1) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
323 | gg_debug(GG_DEBUG_MISC, "=> http, non-critical recv " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
324 | "error (errno=%d, %s)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
325 | errno, strerror(errno)); |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
326 | return 0; |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
327 | } |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
328 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
329 | if (res == 0) { |
| 11360 | 330 | gg_debug(GG_DEBUG_MISC, "=> http, connection reset by peer\n"); |
| 331 | if (h->header) { | |
| 332 | free(h->header); | |
| 333 | h->header = NULL; | |
| 334 | } | |
| 335 | gg_http_error(GG_ERROR_READING); | |
| 336 | } | |
| 337 | ||
| 338 | gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of header\n", res); | |
| 339 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
340 | tmp = realloc(h->header, h->header_size + res + 1); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
341 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
342 | if (tmp == NULL) { |
| 11360 | 343 | gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for header\n"); |
| 344 | free(h->header); | |
| 345 | h->header = NULL; | |
| 346 | gg_http_error(GG_ERROR_READING); | |
| 347 | } | |
| 348 | ||
| 349 | h->header = tmp; | |
| 350 | ||
| 351 | memcpy(h->header + h->header_size, buf, res); | |
| 352 | h->header_size += res; | |
| 353 | ||
| 354 | gg_debug(GG_DEBUG_MISC, "=> http, header_buf=%p, header_size=%d\n", h->header, h->header_size); | |
| 355 | ||
| 356 | h->header[h->header_size] = 0; | |
| 357 | ||
| 358 | if ((tmp = strstr(h->header, "\r\n\r\n")) || (tmp = strstr(h->header, "\n\n"))) { | |
| 359 | int sep_len = (*tmp == '\r') ? 4 : 2; | |
| 360 | unsigned int left; | |
| 361 | char *line; | |
| 362 | ||
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
363 | left = h->header_size - ((size_t)(tmp) - (size_t)(h->header) + sep_len); |
| 11360 | 364 | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
365 | gg_debug(GG_DEBUG_MISC, "=> http, got all header " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
366 | "(%d bytes, %d left)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
367 | h->header_size - left, left); |
| 11360 | 368 | |
| 369 | /* HTTP/1.1 200 OK */ | |
| 370 | if (strlen(h->header) < 16 || strncmp(h->header + 9, "200", 3)) { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
371 | gg_debug(GG_DEBUG_MISC, |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
372 | "=> -----BEGIN-HTTP-HEADER-----\n%s\n" |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
373 | "=> -----END-HTTP-HEADER-----\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
374 | h->header); |
| 11360 | 375 | |
| 376 | gg_debug(GG_DEBUG_MISC, "=> http, didn't get 200 OK -- no results\n"); | |
| 377 | free(h->header); | |
| 378 | h->header = NULL; | |
| 379 | gg_http_error(GG_ERROR_CONNECTING); | |
| 380 | } | |
| 381 | ||
| 382 | h->body_size = 0; | |
| 383 | line = h->header; | |
| 384 | *tmp = 0; | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
385 | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
386 | gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----" |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
387 | "\n%s\n=> -----END-HTTP-HEADER-----\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
388 | h->header); |
| 11360 | 389 | |
| 390 | while (line) { | |
|
18565
6cf6fd1e3d53
Once again revert the g_ascii_strncasecmp/g_ascii_strncasecmp changes here.
Richard Laager <rlaager@pidgin.im>
parents:
18552
diff
changeset
|
391 | if (!strncasecmp(line, "Content-length: ", 16)) { |
| 11360 | 392 | h->body_size = atoi(line + 16); |
| 393 | } | |
| 394 | line = strchr(line, '\n'); | |
| 395 | if (line) | |
| 396 | line++; | |
| 397 | } | |
| 398 | ||
| 399 | if (h->body_size <= 0) { | |
| 400 | gg_debug(GG_DEBUG_MISC, "=> http, content-length not found\n"); | |
| 401 | h->body_size = left; | |
| 402 | } | |
| 403 | ||
|
35214
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
404 | if (h->body_size > GG_HTTP_MAX_LENGTH) { |
|
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
405 | gg_debug(GG_DEBUG_MISC, "=> http, content-length too big\n"); |
|
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
406 | h->body_size = GG_HTTP_MAX_LENGTH; |
|
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
407 | } |
|
ec15aa187aa0
Gadu-Gadu: fix a possible HTTP Content-Length integer overflow (VRT-2013-1001)
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
31826
diff
changeset
|
408 | |
| 11360 | 409 | if (left > h->body_size) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
410 | gg_debug(GG_DEBUG_MISC, "=> http, oversized " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
411 | "reply (%d bytes needed, " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
412 | "%d bytes left)\n", h->body_size, left); |
| 11360 | 413 | h->body_size = left; |
| 414 | } | |
| 415 | ||
| 416 | gg_debug(GG_DEBUG_MISC, "=> http, body_size=%d\n", h->body_size); | |
| 417 | ||
| 418 | if (!(h->body = malloc(h->body_size + 1))) { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
419 | gg_debug(GG_DEBUG_MISC, "=> http, not enough " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
420 | "memory (%d bytes for body_buf)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
421 | h->body_size + 1); |
| 11360 | 422 | free(h->header); |
| 423 | h->header = NULL; | |
| 424 | gg_http_error(GG_ERROR_READING); | |
| 425 | } | |
| 426 | ||
| 427 | if (left) { | |
| 428 | memcpy(h->body, tmp + sep_len, left); | |
| 429 | h->body_done = left; | |
| 430 | } | |
| 431 | ||
| 432 | h->body[left] = 0; | |
| 433 | ||
| 434 | h->state = GG_STATE_READING_DATA; | |
| 435 | h->check = GG_CHECK_READ; | |
| 436 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 437 | } | |
| 438 | ||
| 439 | return 0; | |
| 440 | } | |
| 441 | ||
| 442 | if (h->state == GG_STATE_READING_DATA) { | |
| 443 | char buf[1024]; | |
| 444 | int res; | |
| 445 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
446 | res = recv(h->fd, buf, sizeof(buf), 0); |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
447 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
448 | if (res == -1 && errno != EINTR && errno != EAGAIN) { |
| 11360 | 449 | gg_debug(GG_DEBUG_MISC, "=> http, reading body failed (errno=%d)\n", errno); |
| 450 | if (h->body) { | |
| 451 | free(h->body); | |
| 452 | h->body = NULL; | |
| 453 | } | |
| 454 | gg_http_error(GG_ERROR_READING); | |
| 455 | } | |
| 456 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
457 | if (res == -1) { |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
458 | gg_debug(GG_DEBUG_MISC, "=> http, non-critical " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
459 | "recv error (errno=%d, %s)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
460 | errno, strerror(errno)); |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
461 | return 0; |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
462 | } |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
463 | |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
464 | if (res == 0) { |
| 11360 | 465 | if (h->body_done >= h->body_size) { |
| 466 | gg_debug(GG_DEBUG_MISC, "=> http, we're done, closing socket\n"); | |
| 467 | h->state = GG_STATE_PARSING; | |
| 468 | close(h->fd); | |
| 469 | h->fd = -1; | |
| 470 | } else { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
471 | gg_debug(GG_DEBUG_MISC, "=> http, " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
472 | "connection closed while reading " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
473 | "(have %d, need %d)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
474 | h->body_done, h->body_size); |
| 11360 | 475 | if (h->body) { |
| 476 | free(h->body); | |
| 477 | h->body = NULL; | |
| 478 | } | |
| 479 | gg_http_error(GG_ERROR_READING); | |
| 480 | } | |
| 481 | ||
| 482 | return 0; | |
| 483 | } | |
| 484 | ||
| 485 | gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of body\n", res); | |
| 486 | ||
| 487 | if (h->body_done + res > h->body_size) { | |
| 488 | char *tmp; | |
| 489 | ||
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
490 | gg_debug(GG_DEBUG_MISC, "=> http, too much data " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
491 | "(%d bytes, %d needed), enlarging buffer\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
492 | h->body_done + res, h->body_size); |
| 11360 | 493 | |
| 494 | if (!(tmp = realloc(h->body, h->body_done + res + 1))) { | |
|
35627
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
495 | gg_debug(GG_DEBUG_MISC, "=> http, not enough " |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
496 | "memory for data (%d needed)\n", |
|
fd11790cc4d6
Update internal libgadu to the current version from git
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35617
diff
changeset
|
497 | h->body_done + res + 1); |
| 11360 | 498 | free(h->body); |
| 499 | h->body = NULL; | |
| 500 | gg_http_error(GG_ERROR_READING); | |
| 501 | } | |
| 502 | ||
| 503 | h->body = tmp; | |
| 504 | h->body_size = h->body_done + res; | |
| 505 | } | |
| 506 | ||
| 507 | h->body[h->body_done + res] = 0; | |
| 508 | memcpy(h->body + h->body_done, buf, res); | |
| 509 | h->body_done += res; | |
| 510 | ||
| 511 | gg_debug(GG_DEBUG_MISC, "=> body_done=%d, body_size=%d\n", h->body_done, h->body_size); | |
| 512 | ||
| 513 | return 0; | |
| 514 | } | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
515 | |
| 11360 | 516 | if (h->fd != -1) |
| 517 | close(h->fd); | |
| 518 | ||
| 519 | h->fd = -1; | |
| 520 | h->state = GG_STATE_ERROR; | |
| 521 | h->error = 0; | |
| 522 | ||
| 523 | return -1; | |
| 524 | } | |
| 525 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
526 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
527 | * Kończy asynchroniczne połączenie HTTP. |
| 11360 | 528 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
529 | * Po zatrzymaniu należy zwolnić zasoby funkcją \c gg_http_free(). |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
530 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
531 | * \param h Struktura połączenia |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
532 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
533 | * \ingroup http |
| 11360 | 534 | */ |
| 535 | void gg_http_stop(struct gg_http *h) | |
| 536 | { | |
| 537 | if (!h) | |
| 538 | return; | |
| 539 | ||
| 540 | if (h->state == GG_STATE_ERROR || h->state == GG_STATE_DONE) | |
| 541 | return; | |
| 542 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
543 | h->resolver_cleanup(&h->resolver, 1); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
544 | |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
545 | if (h->fd != -1) { |
| 11360 | 546 | close(h->fd); |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
547 | h->fd = -1; |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
548 | } |
| 11360 | 549 | } |
| 550 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
551 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
552 | * \internal Zwalnia pola struktury \c gg_http. |
| 11360 | 553 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
554 | * Funkcja zwalnia same pola, nie zwalnia struktury. |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
555 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
556 | * \param h Struktura połączenia |
| 11360 | 557 | */ |
| 558 | void gg_http_free_fields(struct gg_http *h) | |
| 559 | { | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
560 | if (h == NULL) |
| 11360 | 561 | return; |
| 562 | ||
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
563 | free(h->body); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
564 | h->body = NULL; |
| 11360 | 565 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
566 | free(h->query); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
567 | h->query = NULL; |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
568 | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
569 | free(h->header); |
|
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
570 | h->header = NULL; |
| 11360 | 571 | } |
| 572 | ||
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
573 | /** |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
574 | * Zwalnia zasoby po połączeniu HTTP. |
| 11360 | 575 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
576 | * Jeśli połączenie nie zostało jeszcze zakończone, jest przerywane. |
| 11360 | 577 | * |
|
29751
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
578 | * \param h Struktura połączenia |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
579 | * |
|
438f88ecc11e
Update our internal libgadu to 1.9.0-rc2. This does not yet build on Windows.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29106
diff
changeset
|
580 | * \ingroup http |
| 11360 | 581 | */ |
| 582 | void gg_http_free(struct gg_http *h) | |
| 583 | { | |
|
35617
c9069e0e3c36
Update internal libgadu to 1.12.0-rc2
Tomasz Wasilczyk <twasilczyk@pidgin.im>
parents:
35214
diff
changeset
|
584 | if (h == NULL) |
| 11360 | 585 | return; |
| 586 | ||
| 587 | gg_http_stop(h); | |
| 588 | gg_http_free_fields(h); | |
| 589 | free(h); | |
| 590 | } | |
| 591 | ||
| 592 | /* | |
| 593 | * Local variables: | |
| 594 | * c-indentation-style: k&r | |
| 595 | * c-basic-offset: 8 | |
| 596 | * indent-tabs-mode: notnil | |
| 597 | * End: | |
| 598 | * | |
| 599 | * vim: shiftwidth=8: | |
| 600 | */ |