Mercurial > audlegacy
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 } |