0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C言語 HTTP通信 ヘッダの中身を表示

Posted at

生データの中身を表示

携帯で接続。
404が出ているが、ヘッダの中身が見れたので気にしない。
image.png

ubuntu@ubuntu:~/kaihatsu/net$ gcc server.c -o server
ubuntu@ubuntu:~/kaihatsu/net$ ./server
ソケット作成成功
ソケットオプション設定
ポート 8080 にバインド成功
接続待機開始...

新しい接続 [192.168.68.163:60116]
▼▼▼ 生リクエストデータ ▼▼▼
GET / HTTP/1.1
Host: 192.168.68.96:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ja-CN;q=0.8,ja;q=0.7


▲▲▲ 生リクエストデータ ▲▲▲

解析結果:
メソッド: GET
リクエストパス: /

初期パスに変換: /index.html
アクセスファイル: public/index.html
ファイル情報:
サイズ: 207 bytes
タイプ: text/html

▼▼▼ レスポンスヘッダ ▼▼▼
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 207

▲▲▲ レスポンスヘッダ ▲▲▲

接続を閉じました

新しい接続 [192.168.68.163:60114]
▼▼▼ 生リクエストデータ ▼▼▼
GET /style.css HTTP/1.1
Host: 192.168.68.96:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36
Accept: text/css,*/*;q=0.1
Referer: http://192.168.68.96:8080/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ja-CN;q=0.8,ja;q=0.7


▲▲▲ 生リクエストデータ ▲▲▲

解析結果:
メソッド: GET
リクエストパス: /style.css

アクセスファイル: public/style.css
ファイル開くのに失敗: No such file or directory
▼▼▼ レスポンスヘッダ ▼▼▼
HTTP/1.1 404 OK
Content-Type: text/plain
Content-Length: 9

▲▲▲ レスポンスヘッダ ▲▲▲

接続を閉じました

新しい接続 [192.168.68.163:60118]
▼▼▼ 生リクエストデータ ▼▼▼
GET /app.js HTTP/1.1
Host: 192.168.68.96:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36
Accept: */*
Referer: http://192.168.68.96:8080/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ja-CN;q=0.8,ja;q=0.7


▲▲▲ 生リクエストデータ ▲▲▲

解析結果:
メソッド: GET
リクエストパス: /app.js

アクセスファイル: public/app.js
ファイル開くのに失敗: No such file or directory
▼▼▼ レスポンスヘッダ ▼▼▼
HTTP/1.1 404 OK
Content-Type: text/plain
Content-Length: 9

▲▲▲ レスポンスヘッダ ▲▲▲

接続を閉じました

Cコード

server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PORT 8080
#define BUFFER_SIZE 2048
#define ROOT_DIR "public/"

// 内容を判定する関数
const char* get_content_type(const char *path) {
    const char *dot = strrchr(path, '.');
    if (dot) {
        if (strcmp(dot, ".css") == 0) return "text/css";
        if (strcmp(dot, ".js") == 0) return "application/javascript";
    }
    return "text/html";
}

// レスポンスを送信する関数
void send_response(int client_fd, int status, const char *content_type, const char *body, int content_length) {
    char header[BUFFER_SIZE];
    snprintf(header, sizeof(header), 
        "HTTP/1.1 %d OK\r\n"
        "Content-Type: %s\r\n"
        "Content-Length: %d\r\n\r\n",
        status, content_type, content_length);
    
    // レスポンスヘッダを表示
    printf("▼▼▼ レスポンスヘッダ ▼▼▼\n");
    printf("%s", header);
    printf("▲▲▲ レスポンスヘッダ ▲▲▲\n\n");
    
    write(client_fd, header, strlen(header));
    write(client_fd, body, content_length);
}

// リクエストを処理する関数
void handle_request(int client_fd) {
    char buffer[BUFFER_SIZE] = {0};
    ssize_t bytes_read = read(client_fd, buffer, sizeof(buffer));
    
    if (bytes_read < 0) {
        perror("リクエストの読み込み失敗");
        return;
    }
    
    // 生のリクエストデータを表示
    printf("▼▼▼ 生リクエストデータ ▼▼▼\n%.*s\n", (int)bytes_read, buffer);
    printf("▲▲▲ 生リクエストデータ ▲▲▲\n\n");
    
    // リクエストヘッダを解析
    char method[16], path[256];
    sscanf(buffer, "%s %s", method, path);
    printf("解析結果:\n");
    printf("メソッド: %s\nリクエストパス: %s\n\n", method, path);
    
    // デフォルトパスの処理
    if (strcmp(path, "/") == 0) {
        strcpy(path, "/index.html");
        printf("初期パスに変換: %s\n", path);
    }
    
    // ローカルファイルパスを構築
    char full_path[512];
    snprintf(full_path, sizeof(full_path), "%s%s", ROOT_DIR, path + 1);
    printf("アクセスファイル: %s\n", full_path);
    
    // ファイルを開く
    int file_fd = open(full_path, O_RDONLY);
    if (file_fd == -1) {
        perror("ファイル開くのに失敗");
        send_response(client_fd, 404, "text/plain", "Not Found", 9);
        return;
    }
    
    // ファイル情報を取得
    struct stat st;
    fstat(file_fd, &st);
    char *content = malloc(st.st_size);
    read(file_fd, content, st.st_size);
    printf("ファイル情報:\nサイズ: %ld bytes\nタイプ: %s\n\n", st.st_size, get_content_type(path));
    
    send_response(client_fd, 200, get_content_type(path), content, st.st_size);
    free(content);
    close(file_fd);
}

int main() {
    int server_fd, client_fd;
    struct sockaddr_in address;
    
    // ソケット作成
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("ソケット作成失敗");
        exit(EXIT_FAILURE);
    }
    printf("ソケット作成成功\n");
    
    // ソケットオプション設定
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    printf("ソケットオプション設定\n");
    
    // アドレスバインド
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("バインド失敗");
        exit(EXIT_FAILURE);
    }
    printf("ポート %d にバインド成功\n", PORT);
    
    // リスニング開始
    if (listen(server_fd, 3) < 0) {
        perror("リスニング失敗");
        exit(EXIT_FAILURE);
    }
    printf("接続待機開始...\n\n");
    
    // メインループ
    while (1) {
        socklen_t addrlen = sizeof(address);
        client_fd = accept(server_fd, (struct sockaddr *)&address, &addrlen);
        if (client_fd < 0) {
            perror("接続受付失敗");
            continue;
        }
        
        // クライアント情報を表示
        char client_ip[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &address.sin_addr, client_ip, INET_ADDRSTRLEN);
        printf("新しい接続 [%s:%d]\n", client_ip, ntohs(address.sin_port));
        
        handle_request(client_fd);
        close(client_fd);
        printf("接続を閉じました\n\n");
    }
    
    return 0;
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?