Submit version 0.20.1 of GUPnP (4186015)
[profile/ivi/GUPnP.git] / tests / gtest / test-context.c
1 /*
2  * Copyright (C) 2012 Nokia.
3  *
4  * Author: Jens Georg <jensg@openismus.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <libsoup/soup.h>
27 #include "libgupnp/gupnp.h"
28
29 static void
30 on_message_finished (SoupSession *session,
31                      SoupMessage *message,
32                      gpointer user_data) {
33         GMainLoop *loop = (GMainLoop*) user_data;
34
35         g_main_loop_quit (loop);
36 }
37
38 static void
39 request_range_and_compare (GMappedFile *file,
40                            SoupSession *session,
41                            GMainLoop   *loop,
42                            const char  *uri,
43                            goffset      want_start,
44                            goffset      want_end)
45 {
46         SoupMessage *message = NULL;
47         goffset      want_length = 0, full_length = 0;
48         goffset      got_start = 0, got_end = 0, got_length = 0;
49         int          result = 0;
50
51         full_length = g_mapped_file_get_length (file);
52
53         /* interpretation according to SoupRange documentation */
54         if (want_end == -1) {
55                 if (want_start < 0)
56                         want_length = -want_start;
57                 else
58                         want_length = full_length - want_start;
59         } else
60                 want_length = want_end - want_start + 1;
61
62         message = soup_message_new ("GET", uri);
63         g_object_ref (message);
64
65         soup_message_headers_set_range (message->request_headers,
66                                         want_start,
67                                         want_end);
68
69         /* interpretation according to SoupRange documentation */
70         if (want_end == -1) {
71                 if (want_start < 0) {
72                         want_length = -want_start;
73                         want_start = full_length + want_start;
74                         want_end = want_start + want_length - 1;
75                 }
76                 else {
77                         want_length = full_length - want_start;
78                         want_end = full_length - 1;
79                 }
80         } else
81                 want_length = want_end - want_start + 1;
82
83
84         soup_session_queue_message (session,
85                                     message,
86                                     on_message_finished,
87                                     loop);
88
89         g_main_loop_run (loop);
90         g_assert_cmpint (message->status_code, ==, SOUP_STATUS_PARTIAL_CONTENT);
91         g_assert_cmpint (message->response_body->length, ==, want_length);
92         got_length = soup_message_headers_get_content_length
93                                         (message->response_headers);
94         g_assert_cmpint (got_length, ==, want_length);
95         soup_message_headers_get_content_range (message->response_headers,
96                                                 &got_start,
97                                                 &got_end,
98                                                 &got_length);
99         g_assert_cmpint (got_start, ==, want_start);
100         g_assert_cmpint (got_end, ==, want_end);
101         result = memcmp (g_mapped_file_get_contents (file) + want_start,
102                          message->response_body->data,
103                          want_length);
104         g_assert_cmpint (result, ==, 0);
105
106         g_object_unref (message);
107
108         message = soup_message_new ("GET", uri);
109         g_object_ref (message);
110 }
111
112 static void
113 test_gupnp_context_http_ranged_requests (void)
114 {
115         GUPnPContext *context = NULL;
116         GError *error = NULL;
117         SoupSession *session = NULL;
118         SoupMessage *message = NULL;
119         guint port = 0;
120         char *uri = NULL;
121         GMainLoop *loop;
122         goffset start, end, length;
123         GMappedFile *file;
124         int result = 0;
125         goffset file_length = 0;
126
127         loop = g_main_loop_new (NULL, FALSE);
128         g_assert (loop != NULL);
129
130         file = g_mapped_file_new (DATA_PATH "/random4k.bin",
131                                   FALSE,
132                                   &error);
133         g_assert (file != NULL);
134         g_assert (error == NULL);
135         file_length = g_mapped_file_get_length (file);
136
137         context = gupnp_context_new (NULL,
138                                      "lo",
139                                      0,
140                                      &error);
141         g_assert (context != NULL);
142         g_assert (error == NULL);
143         port = gupnp_context_get_port (context);
144
145         gupnp_context_host_path (context,
146                                  DATA_PATH "/random4k.bin",
147                                  "/random4k.bin");
148
149         uri = g_strdup_printf ("http://127.0.0.1:%u/random4k.bin", port);
150         g_assert (uri != NULL);
151
152         session = soup_session_async_new ();
153
154         /* Corner cases: First byte */
155         request_range_and_compare (file, session, loop, uri, 0, 0);
156
157         /* Corner cases: Last byte */
158         request_range_and_compare (file,
159                                    session,
160                                    loop,
161                                    uri,
162                                    file_length - 1,
163                                    file_length - 1);
164
165         /* Examples from http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */
166         /* Request first 500 bytes */
167         request_range_and_compare (file, session, loop, uri, 0, 499);
168
169         /* Request second 500 bytes */
170         request_range_and_compare (file, session, loop, uri, 500, 999);
171
172         /* Request everything but the first 500 bytes */
173         request_range_and_compare (file, session, loop, uri, 500, file_length - 1);
174
175         /* Request the last 500 bytes */
176         request_range_and_compare (file, session, loop, uri, file_length - 500, file_length - 1);
177
178         /* Request the last 500 bytes by using negative requests: Range:
179          * bytes: -500 */
180         request_range_and_compare (file, session, loop, uri, -500, -1);
181
182         /* Request the last 1k bytes by using negative requests: Range:
183          * bytes: 3072- */
184         request_range_and_compare (file, session, loop, uri, 3072, -1);
185
186         /* Try to get 1 byte after the end of the file */
187         message = soup_message_new ("GET", uri);
188         g_object_ref (message);
189
190         soup_message_headers_set_range (message->request_headers,
191                                         file_length,
192                                         file_length);
193         soup_session_queue_message (session,
194                                     message,
195                                     on_message_finished,
196                                     loop);
197
198         g_main_loop_run (loop);
199         g_assert_cmpint (message->status_code, ==, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
200
201         g_object_unref (message);
202
203         /* Try with inverted arguments */
204         message = soup_message_new ("GET", uri);
205         g_object_ref (message);
206
207         soup_message_headers_set_range (message->request_headers, 499, 0);
208         soup_session_queue_message (session,
209                                     message,
210                                     on_message_finished,
211                                     loop);
212
213         g_main_loop_run (loop);
214         g_assert_cmpint (message->status_code, ==, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
215
216         g_object_unref (message);
217
218         g_free (uri);
219         g_object_unref (context);
220         g_main_loop_unref (loop);
221         g_mapped_file_unref (file);
222 }
223
224 int main (int argc, char *argv[]) {
225 #if !GLIB_CHECK_VERSION(2,35,0)
226         g_type_init ();
227 #endif
228         g_test_init (&argc, &argv, NULL);
229         g_test_add_func ("/context/http/ranged-requests",
230                          test_gupnp_context_http_ranged_requests);
231
232         g_test_run ();
233
234         return 0;
235 }