tCode added for automatic following of HTTP redirects - vaccinewars - be a doct… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit be798e2756ceb84bf960d15ac83dd1dbd71a0daa | |
parent 322ccf9499188e8f8bf6bd047e326d5fe57cc197 | |
Author: Ben Webb <[email protected]> | |
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(-) | |
--- | |
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,unsign… | |
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; | |
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,unsigne… | |
HttpConnection *OpenMetaHttpConnection(void); | |
void CloseHttpConnection(HttpConnection *conn); | |
gchar *ReadHttpResponse(HttpConnection *conn); | |
+gboolean HandleHttpCompletion(HttpConnection *conn); | |
gboolean HandleWaitingMetaServerData(HttpConnection *conn); | |
void ClearServerList(void); | |
#endif /* NETWORKING */ | |
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,GdkInputCon… | |
g_free(buf); | |
} | |
} | |
- if (!DoneOK) { | |
+ if (!DoneOK && HandleHttpCompletion(MetaConn)) { | |
dopelog(4,"MetaServer: (closed)\n"); | |
- CloseHttpConnection(MetaConn); MetaConn=NULL; | |
+ MetaConn=NULL; | |
if (IsServerShutdown()) GuiQuitServer(); | |
} | |
} |