/*************************************************************************** * * GConnHttp test * * Copyright (C) 2004 Tim-Philipp Müller * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ #define GNET_EXPERIMENTAL 1 #include "conn-http.h" #include #include #undef CONN_HTTP_GTK_DEMO #ifdef CONN_HTTP_GTK_DEMO # include # include # include #endif static gboolean verbose; /* FALSE */ /*************************************************************************** * * http_callback * * Print some information along the way (not required) * ***************************************************************************/ static void http_callback (GConnHttp *http, GConnHttpEvent *event, gpointer baz) { if (!verbose) return; switch (event->type) { case GNET_CONN_HTTP_RESOLVED: { GConnHttpEventResolved *ev_resolved = (GConnHttpEventResolved*)event; if (ev_resolved->ia) g_print ("RESOLVED: %s\n\n", gnet_inetaddr_get_canonical_name(ev_resolved->ia)); else g_print ("RESOLVED: FAILED TO RESOLVE HOSTNAME.\n"); } break; case GNET_CONN_HTTP_RESPONSE: { GConnHttpEventResponse *ev_response = (GConnHttpEventResponse*)event; guint n; g_print("RESPONSE: %u\n", ev_response->response_code); for (n = 0; ev_response->header_fields[n] != NULL; ++n) { g_print("HEADER: %s: %s\n", ev_response->header_fields[n], ev_response->header_values[n]); } g_print("\n"); } break; case GNET_CONN_HTTP_DATA_PARTIAL: { GConnHttpEventData *ev_data = (GConnHttpEventData*)event; if (ev_data->content_length > 0) g_print("PARTIAL DATA: %" G_GUINT64_FORMAT " bytes (%.1f%%)\n", ev_data->data_received, ((gfloat)ev_data->data_received/(gfloat)ev_data->content_length) * 100.0); else g_print("PARTIAL DATA: %" G_GUINT64_FORMAT " bytes (content length unknown)\n", ev_data->data_received); } break; case GNET_CONN_HTTP_DATA_COMPLETE: { GConnHttpEventData *ev_data = (GConnHttpEventData*)event; g_print("\n"); g_print("COMPLETE: %" G_GUINT64_FORMAT " bytes received.\n", ev_data->data_received); } break; case GNET_CONN_HTTP_REDIRECT: { GConnHttpEventRedirect *ev_redir = (GConnHttpEventRedirect*)event; if (!ev_redir->auto_redirect) g_print("REDIRECT: New location => '%s' (not automatic)\n", ev_redir->new_location); else g_print("REDIRECT: New location => '%s' (automatic)\n", ev_redir->new_location); } break; case GNET_CONN_HTTP_CONNECTED: g_print("CONNECTED\n"); break; /* Internal GConnHttp error */ case GNET_CONN_HTTP_ERROR: { GConnHttpEventError *ev_error = (GConnHttpEventError*)event; g_print("ERROR #%u: %s.\n", ev_error->code, ev_error->message); } break; case GNET_CONN_HTTP_TIMEOUT: { g_print("GNET_CONN_HTTP_TIMEOUT.\n"); } break; default: g_assert_not_reached(); } } /*************************************************************************** * * test_get * ***************************************************************************/ static gboolean test_get (const gchar *uri) { GConnHttp *httpconn; gchar *buf; gsize len; httpconn = gnet_conn_http_new(); g_print ("\n=====> Testing GET \n"); if (!gnet_conn_http_set_uri (httpconn, uri)) return FALSE; if (!gnet_conn_http_run (httpconn, http_callback, NULL)) { g_print("\t * GET operation failed.\n"); return FALSE; } gnet_conn_http_steal_buffer(httpconn, &buf, &len); g_print("\t * GET operation ok: received %u bytes.\n", (guint)len); gnet_conn_http_delete(httpconn); g_free(buf); return (len > 0); } /*************************************************************************** * * test_get_binary * ***************************************************************************/ static gboolean test_get_binary (const gchar *uri) { GConnHttp *httpconn; gchar *buf; gsize len; httpconn = gnet_conn_http_new(); g_print ("\n=====> Testing binary GET \n"); if (!gnet_conn_http_set_uri (httpconn, uri)) return FALSE; if (!gnet_conn_http_run (httpconn, NULL, NULL)) { g_print("\t * GET operation failed.\n"); return FALSE; } gnet_conn_http_steal_buffer(httpconn, &buf, &len); g_print("\t * GET operation ok: received %u bytes.\n", (guint)len); #ifdef CONN_HTTP_GTK_DEMO if (1) { GtkWidget *win, *img; gchar *fn; gint fd; /* write image data to temp file */ fd = g_file_open_tmp(NULL, &fn, NULL); if (!fd) { g_print("Could not create temp file: %s\n", g_strerror(errno)); return FALSE; } if (write(fd, buf, len) != len) { g_print("Could not write to temp file: %s\n", g_strerror(errno)); return FALSE; } close(fd); gtk_init(0, NULL); win = gtk_window_new(GTK_WINDOW_TOPLEVEL); img = gtk_image_new_from_file(fn); gtk_container_add(GTK_CONTAINER(win), img); gtk_widget_show_all(win); g_signal_connect(win, "delete-event", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); unlink(fn); g_free(fn); return TRUE; } #else if (!buf || len < 8 || strncmp(buf, "\211PNG\r\n\032\n", 8) != 0) { g_print ("\t * missing PNG signature?!\n"); return FALSE; } g_print ("\t * PNG signature ok\n"); if (len < (8+(4+4)) || strncmp(buf+8+4, "IHDR", 4) != 0) { g_print ("\t * missing IHDR chunk?!\n"); return FALSE; } g_print ("\t * image width x height = %u x %u\n", GUINT32_FROM_BE(*((guint32*)(buf+8+4+4))), GUINT32_FROM_BE(*((guint32*)(buf+8+4+4+4)))); #endif gnet_conn_http_delete(httpconn); g_free(buf); return TRUE; } /*************************************************************************** * * test_redirect * ***************************************************************************/ static gboolean test_redirect (const gchar *uri) { GConnHttp *httpconn; gchar *buf; gsize len; httpconn = gnet_conn_http_new(); g_print ("\n=====> Testing GET with redirect \n"); if (!gnet_conn_http_set_uri (httpconn, uri)) return FALSE; if (!gnet_conn_http_run (httpconn, http_callback, NULL)) { g_print("\t * GET operation with redirect failed.\n"); return FALSE; } gnet_conn_http_steal_buffer(httpconn, &buf, &len); g_print("\t * GET operation with redirect ok: received %u bytes.\n", (guint)len); gnet_conn_http_delete(httpconn); g_free(buf); return TRUE; } /*************************************************************************** * * test_simple_get * * Tests gnet_http_get() * ***************************************************************************/ static gboolean test_simple_get (const gchar *url) { gboolean ret; gchar *buf = NULL; gsize buflen = 0; guint code = 0; g_print ("\n=====> Testing gnet_conn_http_run(): \n"); ret = gnet_http_get (url, &buf, &buflen, &code); if (ret == FALSE) { g_print("\t * gnet_http_get() failed (buflen = %u, code = %u).\n", buflen, code); return FALSE; } g_print("\t * gnet_http_get() succeded (buflen = %u, code = %u).\n", buflen, code); return TRUE; } /*************************************************************************** * * test_post * ***************************************************************************/ static gboolean test_post (const gchar *artist, const gchar *album) { GConnHttp *http; gchar *postdata, *buf, *tag, *artist_esc, *album_esc; gsize buflen; g_print ("\n=====> Testing POST \n"); /* g_markup_printf_escaped() only exists in Glib-2.4 and later */ artist_esc = g_markup_escape_text (artist, -1); album_esc = g_markup_escape_text (album, -1); postdata = g_strdup_printf ( "" "" "" "" "" "" "" "%s" /* <----------- */ "1" "music" "webservices-20" "lite" "" "%s" /* <----------- */ "" "" "", artist_esc, album_esc); g_free (artist_esc); g_free (album_esc); http = gnet_conn_http_new(); if (!gnet_conn_http_set_uri (http, "http://soap.amazon.com/onca/soap3")) return FALSE; if (!gnet_conn_http_set_method (http, GNET_CONN_HTTP_METHOD_POST, postdata, strlen(postdata))) return FALSE; if (!gnet_conn_http_set_header (http, "SOAPAction", "\"http://soap.amazon.com\"", GNET_CONN_HTTP_FLAG_SKIP_HEADER_CHECK)) { g_printerr("gnet_conn_http_set_header(SOAPAction) failed.\n"); return FALSE; } if (!gnet_conn_http_set_header (http, "Content-Type", "text/xml; charset=utf-8", GNET_CONN_HTTP_FLAG_SKIP_HEADER_CHECK)) { g_printerr("gnet_conn_http_set_header(Content-Type) failed.\n"); return FALSE; } if (!gnet_conn_http_run (http, http_callback, postdata)) { g_print("\t * POST operation failed.\n"); return FALSE; } gnet_conn_http_steal_buffer(http, &buf, &buflen); g_print("\t * POST operation ok: received %u bytes.\n", (guint)buflen); tag = strstr(buf, ""); if (tag) { *tag = 0x00; while (tag > buf && *tag != '>') --tag; ++tag; } if (tag && *tag == '$') g_print ("\t * %s, %s - CD Album: ListPrice = %s\n", artist, album, tag); else g_print ("\t * oops, could not find ListPrice for CD Album %s, %s in data returned :|\n", artist, album); gnet_conn_http_delete(http); g_free(postdata); g_free(buf); return TRUE; } /*************************************************************************** * * foo * * Without this, the main loop doesn't want to get going ?! * ***************************************************************************/ static gboolean foo (gpointer baz) { return TRUE; } /*************************************************************************** * * main * ***************************************************************************/ int main (int argc, char **argv) { verbose = FALSE; /* DIRTY HACK. Kids, don't do this at home */ if (argc > 1 && (strcmp(argv[1], "--verbose") == 0 || strcmp(argv[1],"-v") == 0)) { verbose = TRUE; argc--; argv[1] = argv[2]; } /* without this, the GLib mainloop * doesn't seem to get started?! */ g_timeout_add(50, foo, NULL); if (argc > 1) { gboolean ok; ok = test_get(argv[1]); g_print ("------------------------------------------------------------\n"); g_print ("GET (%s): %s\n", argv[1], (ok) ? "OK" : "FAILED"); g_print ("------------------------------------------------------------\n"); g_assert (ok == TRUE); } else { gboolean get_ok, binget_ok, post_ok, redir1_ok, redir2_ok, urlget_ok; get_ok = test_get("http://www.google.com"); post_ok = test_post ("Massive Attack", "Blue Lines"); binget_ok = test_get_binary ("http://www.gnetlibrary.org/gnet.png"); /* Test redirect to different host */ redir1_ok = test_redirect ("http://www.amazon.com"); /* Test redirect to different URL on same host */ redir2_ok = test_redirect ("http://sf.net"); /* Test gnet_http_get() */ urlget_ok = test_simple_get ("http://www.gnetlibrary.org/src/"); g_print ("------------------------------------------------------------\n"); g_print ("GET (html) %s\n", (get_ok) ? "OK" : "FAILED"); g_print ("GET (binary) %s\n", (binget_ok) ? "OK" : "FAILED"); g_print ("POST %s\n", (post_ok) ? "OK" : "FAILED"); g_print ("Redirect (same host) %s\n", (redir1_ok) ? "OK" : "FAILED"); g_print ("Redirect (different host) %s\n", (redir2_ok) ? "OK" : "FAILED"); g_print ("gnet_http_get() %s\n", (urlget_ok) ? "OK" : "FAILED"); g_print ("------------------------------------------------------------\n"); g_assert (get_ok && binget_ok && post_ok && redir1_ok && redir2_ok && urlget_ok); } return EXIT_SUCCESS; }