comparison Plugins/Input/cdaudio/http.c @ 61:fa848bd484d8 trunk

[svn] Move plugins to Plugins/
author nenolod
date Fri, 28 Oct 2005 22:58:11 -0700
parents
children a7b53e6a71e0
comparison
equal deleted inserted replaced
60:1771f253e1b2 61:fa848bd484d8
1 /*
2 * http.c
3 * Some simple routines for connecting to a remote tcp socket
4 * Copyright 1999 Håvard Kvålen <havardk@sol.no>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 /* FIXME: We need to have *one* place in xmms where you configure proxies */
22
23 #include "http.h"
24
25 gint
26 http_open_connection(const gchar * server, gint port)
27 {
28 gint sock;
29 struct hostent *host;
30 struct sockaddr_in address;
31
32 sock = socket(AF_INET, SOCK_STREAM, 0);
33 address.sin_family = AF_INET;
34
35 if (!(host = gethostbyname(server)))
36 return 0;
37
38 memcpy(&address.sin_addr.s_addr, *(host->h_addr_list),
39 sizeof(address.sin_addr.s_addr));
40 address.sin_port = g_htons(port);
41
42 if (connect
43 (sock, (struct sockaddr *) &address,
44 sizeof(struct sockaddr_in)) == -1)
45 return 0;
46
47 return sock;
48 }
49
50 void
51 http_close_connection(gint sock)
52 {
53 shutdown(sock, 2);
54 close(sock);
55 }
56
57 gint
58 http_read_line(gint sock, gchar * buf, gint size)
59 {
60 gint i = 0;
61
62 while (i < size - 1) {
63 if (read(sock, buf + i, 1) <= 0) {
64 if (i == 0)
65 return -1;
66 else
67 break;
68 }
69 if (buf[i] == '\n')
70 break;
71 if (buf[i] != '\r')
72 i++;
73 }
74 buf[i] = '\0';
75 return i;
76 }
77
78 gint
79 http_read_first_line(gint sock, gchar * buf, gint size)
80 {
81 /* Skips the HTTP-header, if there is one, and reads the first line into buf.
82 Returns number of bytes read. */
83
84 gint i;
85 /* Skip the HTTP-header */
86 if ((i = http_read_line(sock, buf, size)) < 0)
87 return -1;
88 if (!strncmp(buf, "HTTP", 4)) { /* Check to make sure its not HTTP/0.9 */
89 while (http_read_line(sock, buf, size) > 0)
90 /* nothing */ ;
91 if ((i = http_read_line(sock, buf, size)) < 0)
92 return -1;
93 }
94
95 return i;
96 }
97
98 gchar *
99 http_get(gchar * url)
100 {
101 gchar *server, *getstr, *buf = NULL, *bptr;
102 gchar *gs, *gc, *turl = url;
103 gint sock, n, bsize, port = 0;
104
105 /* Skip past ``http://'' part of URL */
106 if (!strncmp(turl, "http:", 5)) {
107 turl += 5;
108 if (!strncmp(turl, "//", 2))
109 turl += 2;
110 }
111
112 /* If path starts with a '/', we are referring to localhost */
113 if (turl[0] == '/')
114 server = "localhost";
115 else
116 server = turl;
117
118 /* Check if URL contains port specification */
119 gc = strchr(turl, ':');
120 gs = strchr(turl, '/');
121
122 if (gc != NULL && gc < gs) {
123 port = atoi(gc + 1);
124 *gc = '\0';
125 }
126 if (port == 0)
127 port = 80;
128
129 /* Make sure that server string is null terminated. */
130 if (gs)
131 *gs = '\0';
132
133
134 /*
135 * Now, open connection to server.
136 */
137 sock = http_open_connection(server, port);
138
139 /* Repair the URL string that we broke earlier on */
140 if (gs)
141 *gs = '/';
142 if (gc && gc == '\0')
143 *gc = ':';
144
145 if (sock == 0)
146 return NULL;
147
148 /*
149 * Send query to socket.
150 */
151 getstr = g_strdup_printf("GET %s HTTP/1.0\r\n\r\n", gs ? gs : "/");
152 /* getstr = g_strdup_printf("GET %s HTTP/1.0\r\n\r\n", url ? url : "/"); */
153
154 if (write(sock, getstr, strlen(getstr)) == -1) {
155 http_close_connection(sock);
156 return NULL;
157 }
158
159 /*
160 * Start receiving result.
161 */
162 bsize = 4096;
163 bptr = buf = g_malloc(bsize);
164
165 if ((n = http_read_first_line(sock, bptr, bsize)) == -1) {
166 g_free(buf);
167 buf = NULL;
168 goto Done;
169 }
170
171 bsize -= n;
172 bptr += n;
173
174 while (bsize > 0 && (n = http_read_line(sock, bptr, bsize)) != -1) {
175 bptr += n;
176 bsize -= n;
177 }
178
179 Done:
180 http_close_connection(sock);
181
182 /*
183 * Return result buffer to caller.
184 */
185 return buf;
186 }