tCode added for automatic following of HTTP redirects - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit be798e2756ceb84bf960d15ac83dd1dbd71a0daa
(DIR) parent 322ccf9499188e8f8bf6bd047e326d5fe57cc197
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Thu, 13 Sep 2001 20:21:37 +0000
Code added for automatic following of HTTP redirects
Diffstat:
M src/message.c | 109 ++++++++++++++++++++++---------
M src/message.h | 2 ++
M src/serverside.c | 8 ++++----
3 files changed, 84 insertions(+), 35 deletions(-)
---
(DIR) diff --git a/src/message.c b/src/message.c
t@@ -629,45 +629,22 @@ gboolean WriteDataToWire(NetworkBuffer *NetBuf) {
return TRUE;
}
-HttpConnection *OpenHttpConnection(gchar *HostName,unsigned Port,
- gchar *Proxy,unsigned ProxyPort,
- gchar *Method,gchar *Query,
- gchar *Headers,gchar *Body) {
- HttpConnection *conn;
- gchar *ConnectHost;
- unsigned ConnectPort;
+static void SendHttpRequest(HttpConnection *conn) {
GString *text;
- g_assert(HostName && Method && Query);
-
- conn=g_new0(HttpConnection,1);
- InitNetworkBuffer(&conn->NetBuf,'\n','\r');
- conn->HostName=g_strdup(HostName);
- if (Proxy && Proxy[0]) conn->Proxy=g_strdup(Proxy);
- conn->Method=g_strdup(Method);
- conn->Query=g_strdup(Query);
- if (Headers && Headers[0]) conn->Headers=g_strdup(Headers);
- if (Body && Body[0]) conn->Body=g_strdup(Body);
- conn->Port = Port;
- conn->ProxyPort = ProxyPort;
- if (conn->Proxy) {
- ConnectHost=conn->Proxy; ConnectPort=conn->ProxyPort;
- } else {
- ConnectHost=conn->HostName; ConnectPort=conn->Port;
- }
-
- if (!StartNetworkBufferConnect(&conn->NetBuf,ConnectHost,ConnectPort)) {
- CloseHttpConnection(conn);
- return NULL;
- }
conn->Tries++;
conn->StatusCode=0;
conn->Status=HS_CONNECTING;
text=g_string_new("");
- g_string_sprintf(text,"%s http://%s:%u%s HTTP/1.0",
- conn->Method,conn->HostName,conn->Port,conn->Query);
+ if (conn->Redirect) {
+ g_string_sprintf(text,"%s %s HTTP/1.0",conn->Method,conn->Redirect);
+ g_free(conn->Redirect); conn->Redirect=NULL;
+ } else {
+ g_string_sprintf(text,"%s http://%s:%u%s HTTP/1.0",
+ conn->Method,conn->HostName,conn->Port,conn->Query);
+ }
QueueMessageForSend(&conn->NetBuf,text->str);
if (conn->Headers) QueueMessageForSend(&conn->NetBuf,conn->Headers);
t@@ -681,6 +658,45 @@ HttpConnection *OpenHttpConnection(gchar *HostName,unsigned Port,
if (conn->Body) QueueMessageForSend(&conn->NetBuf,conn->Body);
g_string_free(text,TRUE);
+}
+
+static gboolean StartHttpConnect(HttpConnection *conn) {
+ gchar *ConnectHost;
+ unsigned ConnectPort;
+
+ if (conn->Proxy) {
+ ConnectHost=conn->Proxy; ConnectPort=conn->ProxyPort;
+ } else {
+ ConnectHost=conn->HostName; ConnectPort=conn->Port;
+ }
+
+ if (!StartNetworkBufferConnect(&conn->NetBuf,ConnectHost,ConnectPort)) {
+ CloseHttpConnection(conn);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+HttpConnection *OpenHttpConnection(gchar *HostName,unsigned Port,
+ gchar *Proxy,unsigned ProxyPort,
+ gchar *Method,gchar *Query,
+ gchar *Headers,gchar *Body) {
+ HttpConnection *conn;
+ g_assert(HostName && Method && Query);
+
+ conn=g_new0(HttpConnection,1);
+ InitNetworkBuffer(&conn->NetBuf,'\n','\r');
+ conn->HostName=g_strdup(HostName);
+ if (Proxy && Proxy[0]) conn->Proxy=g_strdup(Proxy);
+ conn->Method=g_strdup(Method);
+ conn->Query=g_strdup(Query);
+ if (Headers && Headers[0]) conn->Headers=g_strdup(Headers);
+ if (Body && Body[0]) conn->Body=g_strdup(Body);
+ conn->Port = Port;
+ conn->ProxyPort = ProxyPort;
+
+ if (!StartHttpConnect(conn)) return NULL;
+ SendHttpRequest(conn);
return conn;
}
t@@ -707,6 +723,7 @@ void CloseHttpConnection(HttpConnection *conn) {
g_free(conn->Query);
g_free(conn->Headers);
g_free(conn->Body);
+ g_free(conn->Redirect);
g_free(conn);
}
t@@ -726,6 +743,18 @@ gchar *ReadHttpResponse(HttpConnection *conn) {
break;
case HS_READHEADERS:
if (msg[0]==0) conn->Status=HS_READSEPARATOR;
+ else {
+ split=g_strsplit(msg," ",1);
+ if (split[0] && split[1]) {
+ if (conn->StatusCode==302 && strcmp(split[0],"Location:")==0) {
+ g_print("Redirect to %s\n",split[1]);
+ g_free(conn->Redirect);
+ conn->Redirect = g_strdup(split[1]);
+ }
+/* g_print("Header %s (value %s) read\n",split[0],split[1]);*/
+ }
+ g_strfreev(split);
+ }
break;
case HS_READSEPARATOR:
conn->Status=HS_READBODY;
t@@ -736,6 +765,24 @@ gchar *ReadHttpResponse(HttpConnection *conn) {
return msg;
}
+gboolean HandleHttpCompletion(HttpConnection *conn) {
+ NBCallBack CallBack;
+ gpointer CallBackData;
+ if (conn->Redirect) {
+ g_print("Following redirect\n");
+ CallBack=conn->NetBuf.CallBack;
+ CallBackData=conn->NetBuf.CallBackData;
+ ShutdownNetworkBuffer(&conn->NetBuf);
+ if (StartHttpConnect(conn)) {
+ SendHttpRequest(conn);
+ SetNetworkBufferCallBack(&conn->NetBuf,CallBack,CallBackData);
+ return FALSE;
+ }
+ }
+ CloseHttpConnection(conn);
+ return TRUE;
+}
+
gboolean HandleWaitingMetaServerData(HttpConnection *conn) {
gchar *msg;
ServerData *NewServer;
(DIR) diff --git a/src/message.h b/src/message.h
t@@ -87,6 +87,7 @@ typedef struct _HttpConnection {
gchar *Query; /* e.g. the path of the desired webpage */
gchar *Headers; /* if non-NULL, e.g. Content-Type */
gchar *Body; /* if non-NULL, data to send */
+ gchar *Redirect; /* if non-NULL, a URL to redirect to */
NetworkBuffer NetBuf; /* The actual network connection itself */
gint Tries; /* Number of requests actually sent so far */
gint StatusCode; /* 0=no status yet, otherwise an HTTP status code */
t@@ -132,6 +133,7 @@ HttpConnection *OpenHttpConnection(gchar *HostName,unsigned Port,
HttpConnection *OpenMetaHttpConnection(void);
void CloseHttpConnection(HttpConnection *conn);
gchar *ReadHttpResponse(HttpConnection *conn);
+gboolean HandleHttpCompletion(HttpConnection *conn);
gboolean HandleWaitingMetaServerData(HttpConnection *conn);
void ClearServerList(void);
#endif /* NETWORKING */
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -893,9 +893,9 @@ void ServerLoop() {
g_free(buf);
}
}
- if (!DoneOK) {
+ if (!DoneOK && HandleHttpCompletion(MetaConn)) {
dopelog(4,"MetaServer: (closed)\n");
- CloseHttpConnection(MetaConn); MetaConn=NULL;
+ MetaConn=NULL;
if (IsServerShutdown()) break;
}
}
t@@ -1010,9 +1010,9 @@ void GuiHandleMeta(gpointer data,gint socket,GdkInputCondition condition) {
g_free(buf);
}
}
- if (!DoneOK) {
+ if (!DoneOK && HandleHttpCompletion(MetaConn)) {
dopelog(4,"MetaServer: (closed)\n");
- CloseHttpConnection(MetaConn); MetaConn=NULL;
+ MetaConn=NULL;
if (IsServerShutdown()) GuiQuitServer();
}
}