J'ai écrit un serveur simple en C qui ne semble pas très différent de tous les exemples que vous trouverez sur Internet. La seule chose qu'il fait est d'écouter le port 80 sur une adresse IP spécifique et de rediriger tout accès à un site différent. Le site redirigé par ce logiciel est mon domaine personnel que j'ai utilisé pendant des années avec nginx. Mon serveur est FreeBSD et fonctionne sur un VPS.Peut accéder au serveur par IP mais pas le nom de domaine
Je désactive le serveur pour le site redirigé et démarre mon programme de serveur personnalisé. Si j'entre l'adresse IP dans la barre d'adresse du navigateur, le serveur fonctionne comme prévu et obtient le statut 302 et redirige vers l'autre site. Si j'entre le nom de domaine dans la barre d'adresse, les navigateurs signalent une erreur "Impossible de se connecter" bien que mon logiciel serveur imprime qu'il a reçu une connexion. Lynx dit,
HTTP/1.1 302 temporaire Redirect
mais se bloque juste là.
Fait intéressant, en faisant curl -I http://example.com/
retours ce que j'attendre:
HTTP/1.1 302 temporaire Redirect
Content-Length: 40
Lieu: https://othersite.com
Je ne Je ne comprends pas pourquoi je suis capable de faire ce travail par IP mais sans utiliser le nom de domaine.
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE 4096 /*max text line length*/
#define SERV_PORT 80 /*port*/
#define LISTENQ 1 /*maximum number of client connections*/
int main (int argc, char **argv)
{
int listenfd, connfd, n;
pid_t childpid;
socklen_t clilen;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;
//Create a socket for the soclet
//If sockfd<0 there was an error in the creation of the socket
if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
perror("Problem in creating the socket");
exit(2);
}
//preparation of the socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");
servaddr.sin_port = htons(SERV_PORT);
//bind the socket
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
//listen to the socket by creating a connection queue, then wait for clients
listen (listenfd, LISTENQ);
for (; ;) {
clilen = sizeof(cliaddr);
//accept a connection
connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &clilen);
if ((childpid = fork()) == 0) {//if it's 0, it's child process
//close listening socket
close (listenfd);
while ((n = recv(connfd, buf, MAXLINE,0)) > 0) {
send(connfd, "HTTP/1.1 302 Temporary Redirect\nContent-Length: 40\nLocation: https://example.org\n\n", 93, 0); //NOTE: I'm aware the length is wrong here due to my editing the name out.
}
exit(0);
}
//close socket of the server
close(connfd);
}
}
Est-ce un problème EOL? Http devrait utiliser CRLF. Il semble que certains clients sont plus tolérants que d'autres. – captncraig
@captncraig Je n'ai eu aucun problème avec CRLF et je pensais lire quelque part que '\ n' est tout ce dont vous avez besoin, mais je l'ai essayé avec' \ r \ n' et cela n'a pas résolu le problème. Notez que cela fonctionne avec une adresse IP. – Rob
Est-ce que l'onglet réseau chrome montre quelque chose d'intéressant? Peut-être une demande de favicon ou quelque chose qui se casse? Je ne suis pas tout à fait le forking, mais il semble que vous fermez l'auditeur après une demande peut-être? – captncraig