Cで単純なHTTPサーバーを1つ作成しようとしていますが、プラットフォーム、Cookieなどを確認するためにブラウザのリクエストを取得する必要があります...そのために、fgets関数でsockファイルを読み取ろうとしていますが、無限に返されますループ。
私のコードを見てください。
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdbool.h>
#define SERVER "TestServer4" //Servername
#define PROTOCOL "HTTP/1.1" //Protocol used
#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT" //Date format of returns
#define PORT 7777 //Socket port
#define NUM_THREADS 5 //Threads clusters numbers
int sock; //Stores the socket
void send_headers(FILE *f, int status, char *title, char *extra, char *mime, int length, time_t date) {
time_t now;
char timebuf[128];
fprintf(f, "%s %d %s\r\n", PROTOCOL, status, title);
fprintf(f, "Server: %s\r\n", SERVER);
now = time(NULL);
strftime(timebuf, sizeof (timebuf), RFC1123FMT, gmtime(&now));
fprintf(f, "Date: %s\r\n", timebuf);
if (extra) fprintf(f, "%s\r\n", extra);
if (mime) fprintf(f, "Content-Type: %s\r\n", mime);
if (length >= 0) fprintf(f, "Content-Length: %d\r\n", length);
if (date != -1) {
strftime(timebuf, sizeof (timebuf), RFC1123FMT, gmtime(&date));
fprintf(f, "Last-Modified: %s\r\n", timebuf);
}
fprintf(f, "Connection: close\r\n");
fprintf(f, "\r\n");
}
void send_error(FILE *f, int status, char *title, char *extra, char *text) {
send_headers(f, status, title, extra, "text/html", -1, -1);
fprintf(f, "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\r\n", status, title);
fprintf(f, "<BODY><H4>%d %s</H4>\r\n", status, title);
fprintf(f, "%s\r\n", text);
fprintf(f, "</BODY></HTML>\r\n");
}
void get_request(FILE *f) {
char buf[4096];
while (fgets(buf, sizeof(buf), f) != NULL) {
fgets(buf, sizeof(buf), f);
printf("%s", buf);
}
}
int process(FILE *f, long tid) {
char buf[4096];
char *method;
char *path;
char *protocol;
struct stat statbuf;
if (!fgets(buf, sizeof(buf), f)) return -1;
get_request(f);
method = strtok(buf, " ");
path = strtok(NULL, " ");
protocol = strtok(NULL, "\r");
if (!method || !path || !protocol) return -1;
fseek(f, 0, SEEK_CUR); // Force change of stream direction
if (strcasecmp(method, "GET") != 0) {
send_error(f, 501, "Not supported", NULL, "Method is not supported.");
} else {
send_headers(f, 200, "OK", NULL, "text/html", -1, statbuf.st_mtime);
bool page = !strcmp(path, "/photos.json");
if (page) {
fprintf(f, "<b> yeah, photos stream :) </b>");
} else {
fprintf(f, "<HTML><HEAD><TITLE>Yeah</TITLE></HEAD>\r\n<BODY>");
fprintf(f, "<H4>server (%s) </H4>\r\n<PRE>\n", path);
}
}
printf("Im running in thread #%ld!\n", tid);
fclose(f);
return 0;
}
void accept_conn(void *threadid) {
long tid;
tid = (long) threadid;
while (1) {
int s;
FILE *f;
s = accept(sock, NULL, NULL);
if (s < 0) {
break;
} else {
f = fdopen(s, "a+");
process(f, tid);
};
}
}
int main(int argc, char *argv[]) {
struct sockaddr_in sin;
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(PORT);
bind(sock, (struct sockaddr *) &sin, sizeof (sin));
listen(sock, 5);
printf("HTTP server listening on port %d\n", PORT);
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, accept_conn, (void *) t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
close(sock);
return 0;
}
問題は get_request 関数にあります。