Mon, 13 Jun 2011 19:22:24 +0000
No more warnings when receiving Gadu-Gadu system messages - fixes #13914
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
1 | /* $Id: http.c 1036 2010-12-15 00:02:28Z wojtekka $ */ |
| 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 | |
| 11360 | 27 | #include <sys/types.h> |
|
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
|
28 | #ifndef _WIN32 |
|
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
|
29 | # include <sys/socket.h> |
|
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
|
30 | # include <netinet/in.h> |
|
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
|
31 | # include <arpa/inet.h> |
|
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
|
32 | #endif |
| 11360 | 33 | |
|
31826
0f6ab56fbf9d
Update libgadu to 0.11.0 plus local changes; thanks to Tomasz Wasilczyk.
Ethan Blanton <elb@pidgin.im>
parents:
31609
diff
changeset
|
34 | #include "compat.h" |
|
0f6ab56fbf9d
Update libgadu to 0.11.0 plus local changes; thanks to Tomasz Wasilczyk.
Ethan Blanton <elb@pidgin.im>
parents:
31609
diff
changeset
|
35 | #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
|
36 | #include "resolver.h" |
| 11360 | 37 | |
| 38 | #include <ctype.h> | |
| 39 | #include <errno.h> | |
|
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
|
40 | #ifndef _WIN32 |
|
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
|
41 | # include <netdb.h> |
|
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
|
42 | #endif |
|
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 | #include <signal.h> |
| 11360 | 44 | #include <stdarg.h> |
| 45 | #include <stdio.h> | |
| 46 | #include <stdlib.h> | |
| 47 | #include <string.h> | |
| 48 | #include <unistd.h> | |
| 49 | ||
|
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
|
50 | /** |
|
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 | * Rozpoczyna połączenie HTTP. |
| 11360 | 52 | * |
|
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
|
53 | * 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
|
54 | * 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
|
55 | * 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
|
56 | * |
|
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 | * 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
|
58 | * 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
|
59 | * deskryptorze (\c fd) i wywołaniu funkcji \c gg_http_watch_fd(). |
| 11360 | 60 | * |
|
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
|
61 | * 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
|
62 | * \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
|
63 | * chwili za pomocą \c gg_http_stop(). |
| 11360 | 64 | * |
|
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
|
65 | * \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
|
66 | * \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
|
67 | * \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
|
68 | * \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
|
69 | * \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
|
70 | * \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
|
71 | * |
|
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
|
72 | * \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
|
73 | * |
|
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
|
74 | * \ingroup http |
| 11360 | 75 | */ |
| 76 | struct gg_http *gg_http_connect(const char *hostname, int port, int async, const char *method, const char *path, const char *header) | |
| 77 | { | |
| 78 | struct gg_http *h; | |
| 79 | ||
| 80 | if (!hostname || !port || !method || !path || !header) { | |
| 81 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n"); | |
| 82 | errno = EFAULT; | |
| 83 | return NULL; | |
| 84 | } | |
|
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
|
85 | |
| 11360 | 86 | if (!(h = malloc(sizeof(*h)))) |
| 87 | return NULL; | |
| 88 | memset(h, 0, sizeof(*h)); | |
| 89 | ||
| 90 | h->async = async; | |
| 91 | h->port = port; | |
| 92 | h->fd = -1; | |
| 93 | h->type = GG_SESSION_HTTP; | |
| 94 | ||
|
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
|
95 | 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
|
96 | |
| 11360 | 97 | if (gg_proxy_enabled) { |
| 98 | char *auth = gg_proxy_auth(); | |
| 99 | ||
| 100 | h->query = gg_saprintf("%s http://%s:%d%s HTTP/1.0\r\n%s%s", | |
| 101 | method, hostname, port, path, (auth) ? auth : | |
| 102 | "", header); | |
| 103 | hostname = gg_proxy_host; | |
| 104 | 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
|
105 | free(auth); |
| 11360 | 106 | |
| 107 | } else { | |
| 108 | h->query = gg_saprintf("%s %s HTTP/1.0\r\n%s", | |
| 109 | method, path, header); | |
| 110 | } | |
| 111 | ||
| 112 | if (!h->query) { | |
| 113 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n"); | |
| 114 | free(h); | |
| 115 | errno = ENOMEM; | |
| 116 | return NULL; | |
| 117 | } | |
|
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
|
118 | |
| 11360 | 119 | gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", h->query); |
| 120 | ||
| 121 | 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
|
122 | if (h->resolver_start(&h->fd, &h->resolver, hostname) == -1) { |
| 11360 | 123 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n"); |
| 124 | gg_http_free(h); | |
| 125 | errno = ENOENT; | |
| 126 | return NULL; | |
| 127 | } | |
| 128 | ||
| 129 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver = %p\n", h->resolver); | |
| 130 | ||
| 131 | h->state = GG_STATE_RESOLVING; | |
| 132 | h->check = GG_CHECK_READ; | |
| 133 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 134 | } else { | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
135 | struct in_addr *addr_list = NULL; |
|
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
136 | int addr_count; |
| 11360 | 137 | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
138 | if (gg_gethostbyname_real(hostname, &addr_list, &addr_count, 0) == -1 || addr_count == 0) { |
| 11360 | 139 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n"); |
| 140 | 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
|
141 | free(addr_list); |
| 11360 | 142 | errno = ENOENT; |
| 143 | return NULL; | |
| 144 | } | |
| 145 | ||
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
146 | if ((h->fd = gg_connect(&addr_list[0], port, 0)) == -1) { |
| 11360 | 147 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() connection failed (errno=%d, %s)\n", errno, strerror(errno)); |
| 148 | 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
|
149 | free(addr_list); |
| 11360 | 150 | return NULL; |
| 151 | } | |
| 152 | ||
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
153 | 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
|
154 | |
| 11360 | 155 | h->state = GG_STATE_CONNECTING; |
| 156 | ||
| 157 | while (h->state != GG_STATE_ERROR && h->state != GG_STATE_PARSING) { | |
| 158 | if (gg_http_watch_fd(h) == -1) | |
| 159 | break; | |
| 160 | } | |
| 161 | ||
| 162 | if (h->state != GG_STATE_PARSING) { | |
| 163 | gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n"); | |
| 164 | gg_http_free(h); | |
| 165 | return NULL; | |
| 166 | } | |
| 167 | } | |
| 168 | ||
| 169 | h->callback = gg_http_watch_fd; | |
| 170 | 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
|
171 | |
| 11360 | 172 | return h; |
| 173 | } | |
| 174 | ||
|
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
|
175 | #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
|
176 | |
| 11360 | 177 | #define gg_http_error(x) \ |
| 178 | close(h->fd); \ | |
| 179 | h->fd = -1; \ | |
| 180 | h->state = GG_STATE_ERROR; \ | |
| 181 | h->error = x; \ | |
| 182 | return 0; | |
| 183 | ||
|
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
|
184 | #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
|
185 | |
|
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 | /** |
|
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 | * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia. |
| 11360 | 188 | * |
|
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
|
189 | * 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
|
190 | * \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
|
191 | * 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
|
192 | * 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
|
193 | * w polu \c error. |
| 11360 | 194 | * |
|
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
|
195 | * \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
|
196 | * |
|
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
|
197 | * \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
|
198 | * |
|
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
|
199 | * \ingroup http |
| 11360 | 200 | */ |
| 201 | int gg_http_watch_fd(struct gg_http *h) | |
| 202 | { | |
| 203 | gg_debug(GG_DEBUG_FUNCTION, "** gg_http_watch_fd(%p);\n", h); | |
| 204 | ||
| 205 | if (!h) { | |
| 206 | gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n"); | |
| 207 | errno = EFAULT; | |
| 208 | return -1; | |
| 209 | } | |
| 210 | ||
| 211 | if (h->state == GG_STATE_RESOLVING) { | |
| 212 | struct in_addr a; | |
| 213 | ||
| 214 | gg_debug(GG_DEBUG_MISC, "=> http, resolving done\n"); | |
| 215 | ||
| 216 | if (read(h->fd, &a, sizeof(a)) < (signed)sizeof(a) || a.s_addr == INADDR_NONE) { | |
| 217 | gg_debug(GG_DEBUG_MISC, "=> http, resolver thread failed\n"); | |
| 218 | gg_http_error(GG_ERROR_RESOLVING); | |
| 219 | } | |
| 220 | ||
| 221 | close(h->fd); | |
| 222 | h->fd = -1; | |
| 223 | ||
|
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
|
224 | h->resolver_cleanup(&h->resolver, 0); |
| 11360 | 225 | |
| 226 | gg_debug(GG_DEBUG_MISC, "=> http, connecting to %s:%d\n", inet_ntoa(a), h->port); | |
| 227 | ||
| 228 | if ((h->fd = gg_connect(&a, h->port, h->async)) == -1) { | |
| 229 | gg_debug(GG_DEBUG_MISC, "=> http, connection failed (errno=%d, %s)\n", errno, strerror(errno)); | |
| 230 | gg_http_error(GG_ERROR_CONNECTING); | |
| 231 | } | |
| 232 | ||
| 233 | h->state = GG_STATE_CONNECTING; | |
| 234 | h->check = GG_CHECK_WRITE; | |
| 235 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 236 | ||
| 237 | return 0; | |
| 238 | } | |
| 239 | ||
| 240 | if (h->state == GG_STATE_CONNECTING) { | |
| 241 | 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
|
242 | socklen_t res_size = sizeof(res); |
| 11360 | 243 | |
| 244 | if (h->async && (getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { | |
| 245 | gg_debug(GG_DEBUG_MISC, "=> http, async connection failed (errno=%d, %s)\n", (res) ? res : errno , strerror((res) ? res : errno)); | |
| 246 | close(h->fd); | |
| 247 | h->fd = -1; | |
| 248 | h->state = GG_STATE_ERROR; | |
| 249 | h->error = GG_ERROR_CONNECTING; | |
| 250 | if (res) | |
| 251 | errno = res; | |
| 252 | return 0; | |
| 253 | } | |
| 254 | ||
| 255 | gg_debug(GG_DEBUG_MISC, "=> http, connected, sending request\n"); | |
| 256 | ||
| 257 | h->state = GG_STATE_SENDING_QUERY; | |
| 258 | } | |
| 259 | ||
| 260 | if (h->state == GG_STATE_SENDING_QUERY) { | |
|
31609
d67fbc90b28a
matekm and kkszysiu collaborated on this patch to update our internal libgadu
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
29752
diff
changeset
|
261 | size_t res; |
| 11360 | 262 | |
| 263 | if ((res = write(h->fd, h->query, strlen(h->query))) < 1) { | |
| 264 | gg_debug(GG_DEBUG_MISC, "=> http, write() failed (len=%d, res=%d, errno=%d)\n", strlen(h->query), res, errno); | |
| 265 | gg_http_error(GG_ERROR_WRITING); | |
| 266 | } | |
| 267 | ||
|
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
|
268 | if (res < strlen(h->query)) { |
| 11360 | 269 | gg_debug(GG_DEBUG_MISC, "=> http, partial header sent (led=%d, sent=%d)\n", strlen(h->query), res); |
| 270 | ||
| 271 | memmove(h->query, h->query + res, strlen(h->query) - res + 1); | |
| 272 | h->state = GG_STATE_SENDING_QUERY; | |
| 273 | h->check = GG_CHECK_WRITE; | |
| 274 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 275 | } else { | |
| 276 | gg_debug(GG_DEBUG_MISC, "=> http, request sent (len=%d)\n", strlen(h->query)); | |
| 277 | free(h->query); | |
| 278 | h->query = NULL; | |
| 279 | ||
| 280 | h->state = GG_STATE_READING_HEADER; | |
| 281 | h->check = GG_CHECK_READ; | |
| 282 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 283 | } | |
| 284 | ||
| 285 | return 0; | |
| 286 | } | |
| 287 | ||
| 288 | if (h->state == GG_STATE_READING_HEADER) { | |
| 289 | char buf[1024], *tmp; | |
| 290 | int res; | |
| 291 | ||
| 292 | if ((res = read(h->fd, buf, sizeof(buf))) == -1) { | |
| 293 | gg_debug(GG_DEBUG_MISC, "=> http, reading header failed (errno=%d)\n", errno); | |
| 294 | if (h->header) { | |
| 295 | free(h->header); | |
| 296 | h->header = NULL; | |
| 297 | } | |
| 298 | gg_http_error(GG_ERROR_READING); | |
| 299 | } | |
| 300 | ||
| 301 | if (!res) { | |
| 302 | gg_debug(GG_DEBUG_MISC, "=> http, connection reset by peer\n"); | |
| 303 | if (h->header) { | |
| 304 | free(h->header); | |
| 305 | h->header = NULL; | |
| 306 | } | |
| 307 | gg_http_error(GG_ERROR_READING); | |
| 308 | } | |
| 309 | ||
| 310 | gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of header\n", res); | |
| 311 | ||
| 312 | if (!(tmp = realloc(h->header, h->header_size + res + 1))) { | |
| 313 | gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for header\n"); | |
| 314 | free(h->header); | |
| 315 | h->header = NULL; | |
| 316 | gg_http_error(GG_ERROR_READING); | |
| 317 | } | |
| 318 | ||
| 319 | h->header = tmp; | |
| 320 | ||
| 321 | memcpy(h->header + h->header_size, buf, res); | |
| 322 | h->header_size += res; | |
| 323 | ||
| 324 | gg_debug(GG_DEBUG_MISC, "=> http, header_buf=%p, header_size=%d\n", h->header, h->header_size); | |
| 325 | ||
| 326 | h->header[h->header_size] = 0; | |
| 327 | ||
| 328 | if ((tmp = strstr(h->header, "\r\n\r\n")) || (tmp = strstr(h->header, "\n\n"))) { | |
| 329 | int sep_len = (*tmp == '\r') ? 4 : 2; | |
| 330 | unsigned int left; | |
| 331 | char *line; | |
| 332 | ||
| 333 | left = h->header_size - ((long)(tmp) - (long)(h->header) + sep_len); | |
| 334 | ||
| 335 | gg_debug(GG_DEBUG_MISC, "=> http, got all header (%d bytes, %d left)\n", h->header_size - left, left); | |
| 336 | ||
| 337 | /* HTTP/1.1 200 OK */ | |
| 338 | if (strlen(h->header) < 16 || strncmp(h->header + 9, "200", 3)) { | |
| 339 | gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header); | |
| 340 | ||
| 341 | gg_debug(GG_DEBUG_MISC, "=> http, didn't get 200 OK -- no results\n"); | |
| 342 | free(h->header); | |
| 343 | h->header = NULL; | |
| 344 | gg_http_error(GG_ERROR_CONNECTING); | |
| 345 | } | |
| 346 | ||
| 347 | h->body_size = 0; | |
| 348 | line = h->header; | |
| 349 | *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
|
350 | |
| 11360 | 351 | gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header); |
| 352 | ||
| 353 | 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
|
354 | if (!strncasecmp(line, "Content-length: ", 16)) { |
| 11360 | 355 | h->body_size = atoi(line + 16); |
| 356 | } | |
| 357 | line = strchr(line, '\n'); | |
| 358 | if (line) | |
| 359 | line++; | |
| 360 | } | |
| 361 | ||
| 362 | if (h->body_size <= 0) { | |
| 363 | gg_debug(GG_DEBUG_MISC, "=> http, content-length not found\n"); | |
| 364 | h->body_size = left; | |
| 365 | } | |
| 366 | ||
| 367 | if (left > h->body_size) { | |
| 368 | gg_debug(GG_DEBUG_MISC, "=> http, oversized reply (%d bytes needed, %d bytes left)\n", h->body_size, left); | |
| 369 | h->body_size = left; | |
| 370 | } | |
| 371 | ||
| 372 | gg_debug(GG_DEBUG_MISC, "=> http, body_size=%d\n", h->body_size); | |
| 373 | ||
| 374 | if (!(h->body = malloc(h->body_size + 1))) { | |
| 375 | gg_debug(GG_DEBUG_MISC, "=> http, not enough memory (%d bytes for body_buf)\n", h->body_size + 1); | |
| 376 | free(h->header); | |
| 377 | h->header = NULL; | |
| 378 | gg_http_error(GG_ERROR_READING); | |
| 379 | } | |
| 380 | ||
| 381 | if (left) { | |
| 382 | memcpy(h->body, tmp + sep_len, left); | |
| 383 | h->body_done = left; | |
| 384 | } | |
| 385 | ||
| 386 | h->body[left] = 0; | |
| 387 | ||
| 388 | h->state = GG_STATE_READING_DATA; | |
| 389 | h->check = GG_CHECK_READ; | |
| 390 | h->timeout = GG_DEFAULT_TIMEOUT; | |
| 391 | } | |
| 392 | ||
| 393 | return 0; | |
| 394 | } | |
| 395 | ||
| 396 | if (h->state == GG_STATE_READING_DATA) { | |
| 397 | char buf[1024]; | |
| 398 | int res; | |
| 399 | ||
| 400 | if ((res = read(h->fd, buf, sizeof(buf))) == -1) { | |
| 401 | gg_debug(GG_DEBUG_MISC, "=> http, reading body failed (errno=%d)\n", errno); | |
| 402 | if (h->body) { | |
| 403 | free(h->body); | |
| 404 | h->body = NULL; | |
| 405 | } | |
| 406 | gg_http_error(GG_ERROR_READING); | |
| 407 | } | |
| 408 | ||
| 409 | if (!res) { | |
| 410 | if (h->body_done >= h->body_size) { | |
| 411 | gg_debug(GG_DEBUG_MISC, "=> http, we're done, closing socket\n"); | |
| 412 | h->state = GG_STATE_PARSING; | |
| 413 | close(h->fd); | |
| 414 | h->fd = -1; | |
| 415 | } else { | |
| 416 | gg_debug(GG_DEBUG_MISC, "=> http, connection closed while reading (have %d, need %d)\n", h->body_done, h->body_size); | |
| 417 | if (h->body) { | |
| 418 | free(h->body); | |
| 419 | h->body = NULL; | |
| 420 | } | |
| 421 | gg_http_error(GG_ERROR_READING); | |
| 422 | } | |
| 423 | ||
| 424 | return 0; | |
| 425 | } | |
| 426 | ||
| 427 | gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of body\n", res); | |
| 428 | ||
| 429 | if (h->body_done + res > h->body_size) { | |
| 430 | char *tmp; | |
| 431 | ||
| 432 | gg_debug(GG_DEBUG_MISC, "=> http, too much data (%d bytes, %d needed), enlarging buffer\n", h->body_done + res, h->body_size); | |
| 433 | ||
| 434 | if (!(tmp = realloc(h->body, h->body_done + res + 1))) { | |
| 435 | gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for data (%d needed)\n", h->body_done + res + 1); | |
| 436 | free(h->body); | |
| 437 | h->body = NULL; | |
| 438 | gg_http_error(GG_ERROR_READING); | |
| 439 | } | |
| 440 | ||
| 441 | h->body = tmp; | |
| 442 | h->body_size = h->body_done + res; | |
| 443 | } | |
| 444 | ||
| 445 | h->body[h->body_done + res] = 0; | |
| 446 | memcpy(h->body + h->body_done, buf, res); | |
| 447 | h->body_done += res; | |
| 448 | ||
| 449 | gg_debug(GG_DEBUG_MISC, "=> body_done=%d, body_size=%d\n", h->body_done, h->body_size); | |
| 450 | ||
| 451 | return 0; | |
| 452 | } | |
|
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
|
453 | |
| 11360 | 454 | if (h->fd != -1) |
| 455 | close(h->fd); | |
| 456 | ||
| 457 | h->fd = -1; | |
| 458 | h->state = GG_STATE_ERROR; | |
| 459 | h->error = 0; | |
| 460 | ||
| 461 | return -1; | |
| 462 | } | |
| 463 | ||
|
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
|
464 | /** |
|
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
|
465 | * Kończy asynchroniczne połączenie HTTP. |
| 11360 | 466 | * |
|
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
|
467 | * 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
|
468 | * |
|
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
|
469 | * \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
|
470 | * |
|
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
|
471 | * \ingroup http |
| 11360 | 472 | */ |
| 473 | void gg_http_stop(struct gg_http *h) | |
| 474 | { | |
| 475 | if (!h) | |
| 476 | return; | |
| 477 | ||
| 478 | if (h->state == GG_STATE_ERROR || h->state == GG_STATE_DONE) | |
| 479 | return; | |
| 480 | ||
|
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
|
481 | if (h->fd != -1) { |
| 11360 | 482 | 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
|
483 | 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
|
484 | } |
|
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
|
485 | |
|
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
|
486 | h->resolver_cleanup(&h->resolver, 1); |
| 11360 | 487 | } |
| 488 | ||
|
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
|
489 | /** |
|
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
|
490 | * \internal Zwalnia pola struktury \c gg_http. |
| 11360 | 491 | * |
|
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
|
492 | * 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
|
493 | * |
|
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
|
494 | * \param h Struktura połączenia |
| 11360 | 495 | */ |
| 496 | void gg_http_free_fields(struct gg_http *h) | |
| 497 | { | |
| 498 | if (!h) | |
| 499 | return; | |
| 500 | ||
| 501 | if (h->body) { | |
| 502 | free(h->body); | |
| 503 | h->body = NULL; | |
| 504 | } | |
| 505 | ||
| 506 | if (h->query) { | |
| 507 | free(h->query); | |
| 508 | h->query = NULL; | |
| 509 | } | |
|
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
|
510 | |
| 11360 | 511 | if (h->header) { |
| 512 | free(h->header); | |
| 513 | h->header = NULL; | |
| 514 | } | |
| 515 | } | |
| 516 | ||
|
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
|
517 | /** |
|
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
|
518 | * Zwalnia zasoby po połączeniu HTTP. |
| 11360 | 519 | * |
|
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
|
520 | * Jeśli połączenie nie zostało jeszcze zakończone, jest przerywane. |
| 11360 | 521 | * |
|
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
|
522 | * \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
|
523 | * |
|
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
|
524 | * \ingroup http |
| 11360 | 525 | */ |
| 526 | void gg_http_free(struct gg_http *h) | |
| 527 | { | |
| 528 | if (!h) | |
| 529 | return; | |
| 530 | ||
| 531 | gg_http_stop(h); | |
| 532 | gg_http_free_fields(h); | |
| 533 | free(h); | |
| 534 | } | |
| 535 | ||
| 536 | /* | |
| 537 | * Local variables: | |
| 538 | * c-indentation-style: k&r | |
| 539 | * c-basic-offset: 8 | |
| 540 | * indent-tabs-mode: notnil | |
| 541 | * End: | |
| 542 | * | |
| 543 | * vim: shiftwidth=8: | |
| 544 | */ |