Merging upstream version 0.7.0 (Closes: #493243, #510888, #567617, #699414, #709777...
[debian/lxpanel.git] / plugins / weather / httputil.c
1 /**
2 * Copyright (c) 2012-2014 Piotr Sipika; see the AUTHORS file for more.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program 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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * See the COPYRIGHT file for more information.
19 */
20
21 /* Provides http protocol utility functions */
22
23 #include "httputil.h"
24
25 #include <libxml/nanohttp.h>
26 #include <libxml/xmlmemory.h>
27
28 #include <string.h>
29
30 /**
31 * Cleans up the nano HTTP state
32 *
33 * @param pContext HTTP Context
34 * @param pContentType Content-type container
35 */
36 static void
37 cleanup(void * pContext, char * pContentType)
38 {
39 if (pContext)
40 {
41 xmlNanoHTTPClose(pContext);
42 }
43
44 if (pContentType)
45 {
46 xmlFree(pContentType);
47 }
48
49 xmlNanoHTTPCleanup();
50 }
51
52 /**
53 * Returns the contents of the requested URL
54 *
55 * @param pczURL The URL to retrieve.
56 * @param piRetCode The return code supplied with the response.
57 * @param piDataSize The resulting data length [out].
58 *
59 * @return A pointer to a null-terminated buffer containing the textual
60 * representation of the response. Must be freed by the caller.
61 */
62 gpointer
63 getURL(const gchar * pczURL, gint * piRetCode, gint * piDataSize)
64 {
65 /* nanohttp magic */
66 gint iBufReadSize = 1024;
67 gint iReadSize = 0;
68 gint iCurrSize = 0;
69
70 gpointer pInBuffer = NULL;
71 gpointer pInBufferRef = NULL;
72
73 gchar cReadBuffer[iBufReadSize];
74 bzero(cReadBuffer, iBufReadSize);
75
76 xmlNanoHTTPInit();
77
78 char * pContentType = NULL;
79 void * pHTTPContext = NULL;
80
81 pHTTPContext = xmlNanoHTTPOpen(pczURL, &pContentType);
82
83 if (!pHTTPContext)
84 {
85 // failure
86 cleanup(pHTTPContext, pContentType);
87
88 *piRetCode = -1;
89
90 return pInBuffer; // it's NULL
91 }
92
93 *piRetCode = xmlNanoHTTPReturnCode(pHTTPContext);
94
95 if (*piRetCode != HTTP_STATUS_OK)
96 {
97 // failure
98 cleanup(pHTTPContext, pContentType);
99
100 return pInBuffer; // it's NULL
101 }
102
103 while ((iReadSize = xmlNanoHTTPRead(pHTTPContext, cReadBuffer, iBufReadSize)) > 0)
104 {
105 // set return code
106 *piRetCode = xmlNanoHTTPReturnCode(pHTTPContext);
107
108 /* Maintain pointer to old location, free on failure */
109 pInBufferRef = pInBuffer;
110
111 pInBuffer = g_try_realloc(pInBuffer, iCurrSize + iReadSize);
112
113 if (!pInBuffer || *piRetCode != HTTP_STATUS_OK)
114 {
115 // failure
116 cleanup(pHTTPContext, pContentType);
117
118 g_free(pInBufferRef);
119
120 return pInBuffer; // it's NULL
121 }
122
123 memcpy(pInBuffer + iCurrSize, cReadBuffer, iReadSize);
124
125 iCurrSize += iReadSize;
126
127 // clear read buffer
128 bzero(cReadBuffer, iBufReadSize);
129
130 *piDataSize = iCurrSize;
131 }
132
133 if (iReadSize < 0)
134 {
135 // error
136 g_free(pInBuffer);
137
138 pInBuffer = NULL;
139 }
140 else
141 {
142 /* Maintain pointer to old location, free on failure */
143 pInBufferRef = pInBuffer;
144
145 // need to add '\0' at the end
146 pInBuffer = g_try_realloc(pInBuffer, iCurrSize + 1);
147
148 if (!pInBuffer)
149 {
150 // failure
151 g_free(pInBufferRef);
152
153 pInBuffer = NULL;
154 }
155 else
156 {
157 memcpy(pInBuffer + iCurrSize, "\0", 1);
158 }
159 }
160
161 // finish up
162 cleanup(pHTTPContext, pContentType);
163
164 return pInBuffer;
165 }