Mercurial > audlegacy-plugins
view src/cdaudio/http.c @ 943:584ab2a62af5 trunk
[svn] - if handle->cancel = TRUE, immediately abort the fread operation.
author | nenolod |
---|---|
date | Thu, 12 Apr 2007 12:02:56 -0700 |
parents | 3da1b8942b8b |
children |
line wrap: on
line source
/* * http.c * Some simple routines for connecting to a remote tcp socket * Copyright 1999 Håvard Kvålen <havardk@sol.no> * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* FIXME: We need to have *one* place in xmms where you configure proxies */ #include "http.h" gint http_open_connection(const gchar * server, gint port) { gint sock; #ifdef USE_IPV6 struct addrinfo hints, *res, *res0; char service[6]; #else struct hostent *host; struct sockaddr_in address; #endif #ifdef USE_IPV6 snprintf(service, 6, "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(server, service, &hints, &res0)) return 0; for (res = res0; res; res = res->ai_next) { sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) { if (res->ai_next) continue; else { freeaddrinfo(res0); return 0; } } if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { if (res->ai_next) { close(sock); continue; } else { freeaddrinfo(res0); return 0; } } freeaddrinfo(res0); return sock; } #else sock = socket(AF_INET, SOCK_STREAM, 0); address.sin_family = AF_INET; if (!(host = gethostbyname(server))) return 0; memcpy(&address.sin_addr.s_addr, *(host->h_addr_list), sizeof(address.sin_addr.s_addr)); address.sin_port = g_htons(port); if (connect (sock, (struct sockaddr *) &address, sizeof(struct sockaddr_in)) == -1) return 0; #endif return sock; } void http_close_connection(gint sock) { shutdown(sock, 2); close(sock); } gint http_read_line(gint sock, gchar * buf, gint size) { gint i = 0; while (i < size - 1) { if (read(sock, buf + i, 1) <= 0) { if (i == 0) return -1; else break; } if (buf[i] == '\n') break; if (buf[i] != '\r') i++; } buf[i] = '\0'; return i; } gint http_read_first_line(gint sock, gchar * buf, gint size) { /* Skips the HTTP-header, if there is one, and reads the first line into buf. Returns number of bytes read. */ gint i; /* Skip the HTTP-header */ if ((i = http_read_line(sock, buf, size)) < 0) return -1; if (!strncmp(buf, "HTTP", 4)) { /* Check to make sure its not HTTP/0.9 */ while (http_read_line(sock, buf, size) > 0) /* nothing */ ; if ((i = http_read_line(sock, buf, size)) < 0) return -1; } return i; } gchar * http_get(gchar * url) { gchar *server, *getstr, *buf = NULL, *bptr; gchar *gs, *gc, *turl = url; gint sock, n, bsize, port = 0; /* Skip past ``http://'' part of URL */ if (!strncmp(turl, "http:", 5)) { turl += 5; if (!strncmp(turl, "//", 2)) turl += 2; } /* If path starts with a '/', we are referring to localhost */ if (turl[0] == '/') server = "localhost"; else server = turl; /* Check if URL contains port specification */ gc = strchr(turl, ':'); gs = strchr(turl, '/'); if (gc != NULL && gc < gs) { port = atoi(gc + 1); *gc = '\0'; } if (port == 0) port = 80; /* Make sure that server string is null terminated. */ if (gs) *gs = '\0'; /* * Now, open connection to server. */ sock = http_open_connection(server, port); /* Repair the URL string that we broke earlier on */ if (gs) *gs = '/'; if (gc && gc == '\0') *gc = ':'; if (sock == 0) return NULL; /* * Send query to socket. */ getstr = g_strdup_printf("GET %s HTTP/1.0\r\n\r\n", gs ? gs : "/"); /* getstr = g_strdup_printf("GET %s HTTP/1.0\r\n\r\n", url ? url : "/"); */ if (write(sock, getstr, strlen(getstr)) == -1) { http_close_connection(sock); return NULL; } /* * Start receiving result. */ bsize = 4096; bptr = buf = g_malloc(bsize); if ((n = http_read_first_line(sock, bptr, bsize)) == -1) { g_free(buf); buf = NULL; goto Done; } bsize -= n; bptr += n; while (bsize > 0 && (n = http_read_line(sock, bptr, bsize)) != -1) { bptr += n; bsize -= n; } Done: http_close_connection(sock); /* * Return result buffer to caller. */ return buf; }