2017-08-23 13 views
0

私は、インターネット上のどのような例とも大きく違わないシンプルなサーバをC言語で書いています。それが行う唯一のことは、特定のIPアドレスでポート80を聞いて、別のサイトへのアクセスをリダイレクトすることです。このソフトウェアによってリダイレクトされているサイトは、私がnginxで長年使ってきた個人的なドメインです。私のサーバはFreeBSDで、VPS上で動作しています。IPでサーバにアクセスできますが、ドメイン名ではありません

リダイレクト先のサイトのサーバーをオフにして、カスタムサーバープログラムを開始しました。ブラウザのアドレスバーにIPアドレスを入力すると、サーバは意図したとおりに動作し、302のステータスを取得し、他のサイトにリダイレクトします。アドレスバーにドメイン名を入力すると、サーバソフトウェアが接続を受け取ったことを表示するにもかかわらず、ブラウザは「接続できません」というエラーを表示します。 Lynxは、言う

HTTP/1.1 302一時的なリダイレクト

ちょうどそこにハングアップします。

HTTP/1.1 302一時的なリダイレクト

のContent-Length:40

場所:https://othersite.com

Iドン私が期待する何curl -I http://example.com/リターンをやっ興味深いことに

、なぜ私はIPでこの仕事をすることができますが、ドメイン名を使用することはできません理解していない。

#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); 
} 
} 
+1

EOLの問題ですか? HTTPはCRLFを使用する必要があります。一部のクライアントは他のクライアントよりも耐性があるようです。 – captncraig

+0

@captncraig私はCRLFに何の問題もなく、 '\ n'はあなたが必要とするものだけを読んでいると思っていましたが、' \ r \ n'で試してみましたが問題は解決しませんでした。これはIPアドレスで動作することに注意してください。 – Rob

+0

クロムネットワークタブには何か興味深いものがありますか?多分faviconの要求か何かそれを台無しにする?私はフォークをかなりフォローしていませんが、1回のリクエストの後にリスナーを閉じるようですか? – captncraig

答えて

0

私がこれをうまく動作させるために非常に多くの問題を抱えていた理由は簡単です。私は\ nがの1つのの制御文字であることを忘れていましたが、長さを2として数えていました。

さらに、このサイトはもともと、httpからリダイレクトしようとしている間、ブラウザが覚えて自動的にhttpsバージョンにアクセスしようとするHSTSを送信していました。だからこそ、なぜ私はこれをLynxとカールで動作させることができるのかを説明しますが、他のものではありません。

関連する問題