2017-08-23 121 views
0

我用C寫了一個簡單的服務器,與您在互聯網上找到的任何示例都沒有多大區別。它所做的唯一的事情是在特定IP地址上監聽端口80,並將任何訪問重定向到其他站點。被這個軟件重定向的網站是我用nginx多年來使用的個人域名。我的服務器是FreeBSD,它運行在VPS上。可以通過IP訪問服務器,但不能通過域名訪問服務器

我關閉了重定向站點的服務器並啓動了我的自定義服務器程序。如果我在瀏覽器的地址欄中輸入IP地址,則服務器按預期工作,並獲得302狀態並重定向到其他站點。如果我在地址欄中輸入域名,瀏覽器會給出「無法連接」的錯誤,儘管我的服務器軟件會打印它接收到的連接。山貓說,

HTTP/1.1 302臨時重定向

,但只是掛在那兒。

有趣的是,在做curl -I http://example.com/回報我期望:

HTTP/1.1 302臨時重定向

的Content-Length:40

地點:https://othersite.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

鉻網絡選項卡顯示什麼有趣的?也許一個收藏夾圖標請求或東西搞砸了?我不太喜歡分叉,但似乎你在一個請求後關閉了聽衆? – captncraig

回答

0

我有這麼多問題得到這個工作的原因很簡單。我忘記了\ n是一個控制字符,但它的長度計爲兩個。

此外,該網站最初發送的瀏覽器會記住並自動嘗試訪問https版本,而我試圖從http重定向的HSTS。所以這就解釋了爲什麼我可以用l and和捲曲工作而不是其他工作。

相關問題