Serveur proxy http (win32)

Soyez le premier à donner votre avis sur cette source.

Vue 10 443 fois - Téléchargée 740 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
-
Ç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
-
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
-
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
-
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
-
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.