Serveur proxy http (win32)

Soyez le premier à donner votre avis sur cette source.

Vue 10 820 fois - Téléchargée 823 fois

Description

C'est un mini-proxy écrit en C, mono-threadé et ne gérant que la commande GET du protocole HTTP/1.1 (une autre version provoquant une erreur).

J'ajouterais la gestion des erreurs sockets, une architecture multi-threads ainsi que le support de la commande POST quand l'envie m'en prendra...

C'est toutefois une bonne base de départ pour coder un proxy, donc si vous l'améliorez, n'hésitez pas à me faire parvenir votre travail ;)

Source / Exemple :


#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <string.h>

#define HTTP_400_BEGIN "HTTP/1.1 200 OK\r\nServer: mProxy/1.0\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><head><title>400 - BAD REQUEST</title></head><body bgcolor=white text=black><h1>Unknown protocol</h1><blockquote><pre>\r\n"
#define HTTP_400_END "</pre></blockquote><hr><div align=right>mProxy by <a href=\"mailto:caranarchie@laposte.net\">Gab's</a></div></body></html>\r\n"

#define HTTP_404_BEGIN "HTTP/1.1 200 OK\r\nServer: mProxy/1.0\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><head><title>404 - NOT FOUND</title></head><body bgcolor=white text=black><h1>Unknown host</h1><blockquote><pre>\r\n"
#define HTTP_404_END "</pre></blockquote><hr><div align=right>mProxy by <a href=\"mailto:caranarchie@laposte.net\">Gab's</a></div></body></html>\r\n"

#define HTTP_501_BEGIN "HTTP/1.1 200 OK\r\nServer: mProxy/1.0\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><head><title>501 - NOT IMPLEMENTED</title></head><body bgcolor=white text=black><h1>Unknown request</h1><blockquote><pre>\r\n"
#define HTTP_501_END "</pre></blockquote><hr><div align=right>mProxy by <a href=\"mailto:caranarchie@laposte.net\">Gab's</a></div></body></html>\r\n"

void PutStr(char** r, char* s) {
  int x = strlen(s) + 1;
  int n = (*r) ? strlen(*r) : 0;

  • r = (char*) realloc(*r, x + n);
memcpy(*r + n, s, x); } int main(int argc, char* argv[]) { WSADATA WSAData; SOCKADDR_IN ServerSock; int ServerSockSize = sizeof(ServerSock); SOCKET Server = INVALID_SOCKET; SOCKADDR_IN ClientSock; int ClientSockSize = sizeof(ClientSock); SOCKET Client = INVALID_SOCKET; WSAStartup(MAKEWORD(2, 2), &WSAData); memset(&ServerSock, 0, ServerSockSize); ServerSock.sin_family = AF_INET; ServerSock.sin_port = htons(8080); ServerSock.sin_addr.s_addr = htonl(INADDR_ANY); Server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bind(Server, (SOCKADDR*) &ServerSock, ServerSockSize); listen(Server, SOMAXCONN); while (1) { int i = 0; int n = 0; char c = 0; char* p = NULL; char* r = NULL; char* cv = NULL; int cl = 0; memset(&ClientSock, 0, ClientSockSize); Client = accept(Server, (SOCKADDR*) &ClientSock, &ClientSockSize); while (recv(Client, &c, 1, 0) > 0) { r = (char*) realloc(r, i + 1); r[i++] = c; if (c == '\r' || c == '\n') { if (++n == 4) break; } else n = 0; } r = (char*) realloc(r, i + 1); r[i] = '\0'; p = strstr(r, "Content-Length: "); if (p) { int i = 0; p += 16; while (*p != '\r' && *p != '\n') { cv = (char*) realloc(cv, i + 1); cv[i++] = *p; p++; } cl = atoi(cv); free(cv); cv = (char*) malloc(cl + 1); recv(Client, cv, cl, 0); cv[cl] = '\0'; } if (r[0] != 'G' || r[1] != 'E' || r[2] != 'T' || r[3] != ' ') { send(Client, HTTP_501_BEGIN, strlen(HTTP_501_BEGIN), 0); send(Client, r, i, 0); if (cv) send(Client, cv, cl, 0); send(Client, HTTP_501_END, strlen(HTTP_501_END), 0); } else { char* p = strstr(r, " HTTP/"); if (p[6] != '1' || p[7] != '.' || p[8] != '1') { send(Client, HTTP_400_BEGIN, strlen(HTTP_400_BEGIN), 0); send(Client, r, i, 0); if (cv) send(Client, cv, cl, 0); send(Client, HTTP_400_END, strlen(HTTP_400_END), 0); } else { char* p = r; char* host = NULL; char* port = NULL; char* location = NULL; HOSTENT* mProxyAddr = NULL; while (p[0] != 'H' || p[1] != 'o' || p[2] != 's' || p[3] != 't' || p[4] != ':' || p[5] != ' ') p++; p += 6; host = p; while (*p != ':' && *p != '\r' && *p != '\n') p++; if (*p == ':') {
  • p = '\0';
port = p + 1; while (*p != '\r' && *p != '\n') p++; } else port = "80";
  • p = '\0';
p = strstr(r, "://"); location = (p) ? p + 3 : r + 4; while (*location != '/') location++;
  • (strstr(location, " HTTP/")) = '\0';
mProxyAddr = gethostbyname(host); if (mProxyAddr) { SOCKADDR_IN mProxySock; int mProxySockSize = sizeof(mProxySock); SOCKET mProxy = INVALID_SOCKET; memset(&mProxySock, 0, mProxySockSize); memcpy(&mProxySock.sin_addr.s_addr, mProxyAddr->h_addr, mProxyAddr->h_length); mProxySock.sin_port = htons(atoi(port)); mProxySock.sin_family = AF_INET; mProxy = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connect(mProxy, (SOCKADDR*) &mProxySock, mProxySockSize)) { send(Client, HTTP_404_BEGIN, strlen(HTTP_404_BEGIN), 0); send(Client, host, strlen(host), 0); send(Client, ":", 1, 0); send(Client, port, strlen(port), 0); send(Client, HTTP_404_END, strlen(HTTP_404_END), 0); } else { char* r = NULL; PutStr(&r, "GET "); PutStr(&r, location); PutStr(&r, " HTTP/1.1"); PutStr(&r, "\r\n"); PutStr(&r, "User-Agent: mProxy/1.0"); PutStr(&r, "\r\n"); PutStr(&r, "Host: "); PutStr(&r, host); PutStr(&r, ":"); PutStr(&r, port); PutStr(&r, "\r\n"); PutStr(&r, "Connection: close"); PutStr(&r, "\r\n"); PutStr(&r, "\r\n"); send(mProxy, r, strlen(r), 0); free(r); while (recv(mProxy, &c, 1, 0) > 0) send(Client, &c, 1, 0); shutdown(mProxy, SD_BOTH); closesocket(mProxy); } } else { send(Client, HTTP_404_BEGIN, strlen(HTTP_404_BEGIN), 0); send(Client, host, strlen(host), 0); send(Client, ":", 1, 0); send(Client, port, strlen(port), 0); send(Client, HTTP_404_END, strlen(HTTP_404_END), 0); } } } shutdown(Client, SD_BOTH); closesocket(Client); free(r); } }

Conclusion :


Je ne l'ai pas codé pour un projet particulier, donc les mises à jour seront plus que très certainement poussives...

A faire :
- gestion erreurs sockets
- passage en multithreads
- gestion commande POST
- gestion Referer, Cookie, etc...

Une fois ceci fait, il devrait etre fonctionnel pour la grande majorité des sites ;)

Codes Sources

A voir également

Ajouter un commentaire Commentaires
blablahh Messages postés 1 Date d'inscription mercredi 27 décembre 2000 Statut Membre Dernière intervention 19 novembre 2008
19 nov. 2008 à 07:33
Ça ne vous dirait pas de vous mettre à l'objet? On pourrait y comprendre quelque chose, plus que ce code rigide et procédural!
fatilama Messages postés 1 Date d'inscription mercredi 16 avril 2008 Statut Membre Dernière intervention 18 avril 2008
18 avril 2008 à 11:53
bonjour.
Est ce que vous pouvez ajouter les commentaires principauxa propos de ta source svp?
Merci
psyphi Messages postés 51 Date d'inscription lundi 16 août 2004 Statut Membre Dernière intervention 12 août 2010
18 avril 2006 à 17:19
Est ce que tu pourrais commenté un peu plus ta source stp?
cs_tamsir Messages postés 9 Date d'inscription samedi 9 mars 2002 Statut Membre Dernière intervention 20 novembre 2005
20 nov. 2005 à 20:36
oui opaceque c'est un serveur, il et en attente de connexion lol
amodels Messages postés 17 Date d'inscription jeudi 31 juillet 2003 Statut Membre Dernière intervention 17 juillet 2006
28 nov. 2003 à 21:50
Bonjour,
Qd je lance le .exe, aucun résultat, est-ce normal ?
merci

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.