Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
A donation makes a contribution towards the costs, the time and effort that's going in this site and building.
Thank You! Steffen
Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
| |
|
Topic: method PUT is not allowed for this URL |
|
| Author |
|
oliv2831
Joined: 16 Mar 2026 Posts: 4
|
Posted: Mon 16 Mar '26 19:57 Post subject: method PUT is not allowed for this URL |
|
|
Hello,
My goal is to configure an 2.4.66 Apache instance on Debian 13 to accept file uploads from local IP phones using PUT method.
I've tested many combinations of the following config:
| Code: | <VirtualHost *:80>
ServerAdmin jdoe@example.com
Alias / /srv/tftp/
DocumentRoot /srv/tftp/
LogLevel debug
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/srv/tftp/">
Options Indexes FollowSymLinks
AllowOverride None
<Limit GET POST OPTIONS PUT DELETE>
Require all granted
</Limit>
</Directory>
<Location "/yealink/uploads/toto.txt">
AllowMethods GET POST OPTIONS PUT DELETE
Script PUT /cgi-bin/file_upload.php
</Location>
</VirtualHost> |
I'm testing with :
curl --verbose -T /tmp/toto.txt http://192.168.4.5/yealink/uploads/toto.txt
...
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method PUT is not allowed for this URL.</p>
Error.log shows:
| Code: | [Mon Mar 16 18:40:58.257519 2026] [authz_core:debug] [pid 66299:tid 66306] mod_authz_core.c(815): [client 192.168.4.187:56986] AH01626: authorization result of Require all granted: granted
[Mon Mar 16 18:40:58.257768 2026] [authz_core:debug] [pid 66299:tid 66306] mod_authz_core.c(815): [client 192.168.4.187:56986] AH01626: authorization result of <RequireAny>: granted
[Mon Mar 16 18:40:58.257880 2026] [authz_core:debug] [pid 66299:tid 66306] mod_authz_core.c(815): [client 192.168.4.187:56986] AH01626: authorization result of Require all granted: granted
[Mon Mar 16 18:40:58.257888 2026] [authz_core:debug] [pid 66299:tid 66306] mod_authz_core.c(815): [client 192.168.4.187:56986] AH01626: authorization result of <RequireAny>: granted |
My script file /usr/lib/cgi-bin/file_upload.php is:
| Quote: | <?php
error_log("Current user is ".get_current_user());
$data = file_get_contents("php://input");
//$output_filename = $_SERVER['DOCUMENT_ROOT'].$_SERVER['REQUEST_URI'];
$output_filename = $_SERVER['DOCUMENT_ROOT'].$_SERVER['PATH_INFO'];
$code = file_put_contents($output_filename, $data);
if (strlen($data) !== $code)
error_log("Error code while writing ".$output_filename.": input length is ".strlen($data)." while output length is ".$code);
?> |
How can I get this working ?
Best regards |
|
| Back to top |
|
Stray78

Joined: 15 Apr 2024 Posts: 59 Location: USA
|
Posted: Mon 16 Mar '26 21:51 Post subject: |
|
|
| Do you have mod_actions enabled? |
|
| Back to top |
|
oliv2831
Joined: 16 Mar 2026 Posts: 4
|
Posted: Tue 17 Mar '26 9:54 Post subject: method PUT is not allowed for this URL |
|
|
| Yes mod_actions is enabled. |
|
| Back to top |
|
oliv2831
Joined: 16 Mar 2026 Posts: 4
|
Posted: Tue 17 Mar '26 12:11 Post subject: |
|
|
| Code: | apachectl -t -D DUMP_MODULES
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.64.250. Set the 'ServerName' directive globally to suppress this message
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
actions_module (shared)
alias_module (shared)
allowmethods_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cgid_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
filter_module (shared)
mime_module (shared)
mpm_event_module (shared)
negotiation_module (shared)
reqtimeout_module (shared)
setenvif_module (shared)
status_module (shared) |
|
|
| Back to top |
|
oliv2831
Joined: 16 Mar 2026 Posts: 4
|
Posted: Wed 18 Mar '26 14:38 Post subject: [SOLVED] method PUT is not allowed for this URL |
|
|
I could use PUT method after enabling Dav module.
I'm inclined to now think AllowMethods cannot add new methods such as PUT but I'm far from certain about that. |
|
| Back to top |
|
Stray78

Joined: 15 Apr 2024 Posts: 59 Location: USA
|
Posted: Fri 20 Mar '26 22:43 Post subject: |
|
|
So I dont have time to test myself but I threw it into ChatGPT and got this...
You’re very close, but the key issue is this:
👉 Apache is rejecting the PUT request before it ever reaches your CGI/PHP script.
That’s why you see:
405 Method Not Allowed
“The requested method PUT is not allowed for this URL.”
Even though your <Limit> and <Location> blocks look permissive, Apache does not natively support PUT to arbitrary files unless a specific handler/module is in place.
🔴 Root cause
Apache only allows PUT when:
A module like mod_dav is handling it, or
The request is routed to a script that explicitly handles PUT (CGI, PHP, etc.)
Right now:
You’re sending PUT to /yealink/uploads/toto.txt
Apache tries to treat it as a static file
Since no handler owns PUT → 405
Your Script PUT /cgi-bin/file_upload.php line is the main problem:
👉 That directive does not exist in Apache (so it’s ignored)
✅ Solution options
✅ Option 1 (simplest): Use POST instead of PUT
If you control the client (curl works fine):
| Code: | | curl -F "file=@/tmp/toto.txt" http://192.168.4.5/cgi-bin/file_upload.php |
Then handle via $_FILES in PHP.
👉 This is the easiest and most reliable path.
✅ Option 2: Properly handle PUT via CGI/PHP
You must route the request to a script, not a file path.
✔ Fix your config
Replace your <Location> block with something like:
| Code: |
ScriptAlias /upload /usr/lib/cgi-bin/file_upload.php
<Location /upload>
Require all granted
</Location> |
✔ Then call:
| Code: | | curl -T /tmp/toto.txt http://192.168.4.5/upload/toto.txt |
✔ Fix your PHP
Your PHP is close, but use this:
| Code: | <?php
$data = file_get_contents("php://input");
$path = $_SERVER['PATH_INFO'] ?? '/uploaded.bin';
$file = '/srv/tftp' . $path;
file_put_contents($file, $data);
?> |
✅ Option 3 (most “Apache-native”): Use WebDAV
If you really want true PUT-to-filesystem behavior:
Enable modules:
| Code: | a2enmod dav
a2enmod dav_fs |
Config:
| Code: | DavLockDB /var/lib/dav/lockdb
Alias /uploads /srv/tftp
<Directory /srv/tftp>
Dav On
Require all granted
</Directory> |
Now PUT will work directly:
| Code: | | curl -T /tmp/toto.txt http://192.168.4.5/uploads/toto.txt |
⚠️ Important gotchas
1. Permissions
Make sure Apache can write:
| Code: | chown -R www-data:www-data /srv/tftp
chmod -R 755 /srv/tftp |
2. SELinux / AppArmor (Debian usually AppArmor)
May silently block writes.
3. <Limit> block
This part is fine but not sufficient:
| Code: | <LimitExcept GET POST OPTIONS PUT DELETE>
Require all granted
</LimitExcept> |
👉 It only controls authorization, not method handling
💡 Bottom line
Your config allows PUT authorization-wise ✅
But Apache has no handler for PUT ❌
So it returns 405 before PHP runs
✔ Recommended fix
If this is for IP phones (Yealink):
👉 Use WebDAV (Option 3) — it’s exactly what they expect.
If you want, tell me:
your exact Yealink model
firmware version
I can give you a drop-in working config specifically for that device 👍 |
|
| Back to top |
|
|
|
|
|
|