0

I'm trying to post a comment to The API Sandbox, I did one using the interactive documentation, but when trying to use my own code, it doesn't work. Instead, I get status code 405 (Method not allowed)

const http = require("http")
let req = http.request({
    method: "POST",
    href: `https://api.stackexchange.com/2.3/posts/51812/comments/add?site=meta&access_token=my_access_token&key=app_key&body=${encodeURI("Testing comment with enough length")}&preview=false`,
    headers: {
        "Content-Type": "application/json"
    }
}, res => {
    console.log(`code: ${res.statusCode}`) // "code: 405"
    res.on("error", console.error)
})
req.end()

I don't really understand how I'm supposed to post the comment. Did I make a mistake?

Removing method: "POST" gives status code 200, but still doesn't post a comment.

Also, when using res.on("data"), for some reason it sends back this webpage:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IIS 10.0 Detailed Error - 405.0 - Method Not Allowed</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;}
code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;}
.config_source code{font-size:.8em;color:#000000;}
pre{margin:0;font-size:1.4em;word-wrap:break-word;}
ul,ol{margin:10px 0 10px 5px;}
ul.first,ol.first{margin-top:5px;}
fieldset{padding:0 15px 10px 15px;word-break:break-all;}
.summary-container fieldset{padding-bottom:5px;margin-top:4px;}
legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;}
legend{color:#333333;;margin:4px 0 8px -12px;_margin-top:0px;
font-weight:bold;font-size:1em;}
a:link,a:visited{color:#007EFF;font-weight:bold;}
a:hover{text-decoration:none;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.4em;margin:10px 0 0 0;color:#CC0000;}
h4{font-size:1.2em;margin:10px 0 5px 0;
}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif;       
 color:#FFF;background-color:#5C87B2;
}#content{margin:0 0 0 2%;position:relative;}
.summary-container,.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
.content-container p{margin:0 0 10px 0;
}#details-left{width:35%;float:left;margin-right:2%;
}#details-right{width:63%;float:left;overflow:hidden;
}#server_version{width:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF; 
 background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal;   
 font-size:1em;color:#FFF;text-align:right;
}#server_version p{margin:5px 0;}
table{margin:4px 0 4px 0;width:100%;border:none;}
td,th{vertical-align:top;padding:3px 0;text-align:left;font-weight:normal;border:none;}
th{width:30%;text-align:right;padding-right:2%;font-weight:bold;}
thead th{background-color:#ebebeb;width:25%;
}#details-right th{width:20%;}
table tr.alt td,table tr.alt th{}
.highlight-code{color:#CC0000;font-weight:bold;font-style:italic;}
.clear{clear:both;}
.preferred{padding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em;}
-->
</style>

</head>
<body>
<div id="content">
<div class="content-container">
  <h3>HTTP Error 405.0 - Method Not Allowed</h3>
  <h4>The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.</h4>
</div>
<div class="content-container">
 <fieldset><h4>Most likely causes:</h4>
  <ul>  <li>The request sent to the Web server used an HTTP verb that is not allowed by the module configured to handle the request.</li>    <li>A request was sent to the server that contained an invalid HTTP verb.</li>       <li>The request is for static content and contains an HTTP verb other than GET or HEAD.</li>    <li>A request was sent to a virtual directory using the HTTP verb POST and the default document is a static file that does not support HTTP verbs other than GET or HEAD.</li> </ul>
 </fieldset>
</div>
<div class="content-container">
 <fieldset><h4>Things you can try:</h4>
  <ul>  <li>Verify the list of verbs enabled for the module handler this request was sent to, and ensure that this verb should be allowed for the Web site.</li>     <li>Check the IIS log file to see which verb is not allowed for the request.</li>    <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click <a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>. </li> </ul>
 </fieldset>
</div>

<div class="content-container">
 <fieldset><h4>Detailed Error Information:</h4>
  <div id="details-left">
   <table border="0" cellpadding="0" cellspacing="0">
    <tr class="alt"><th>Module</th><td>&nbsp;&nbsp;&nbsp;StaticFileModule</td></tr>
    <tr><th>Notification</th><td>&nbsp;&nbsp;&nbsp;ExecuteRequestHandler</td></tr>
    <tr class="alt"><th>Handler</th><td>&nbsp;&nbsp;&nbsp;StaticFile</td></tr>
    <tr><th>Error Code</th><td>&nbsp;&nbsp;&nbsp;0x80070001</td></tr>

   </table>
  </div>
  <div id="details-right">
   <table border="0" cellpadding="0" cellspacing="0">
    <tr class="alt"><th>Requested URL</th><td>&nbsp;&nbsp;&nbsp;http://localhost:80/iisstart.htm</td></tr>   
    <tr><th>Physical Path</th><td>&nbsp;&nbsp;&nbsp;C:\inetpub\wwwroot\iisstart.htm</td></tr>
    <tr class="alt"><th>Logon Method</th><td>&nbsp;&nbsp;&nbsp;Anonymous</td></tr>
    <tr><th>Logon User</th><td>&nbsp;&nbsp;&nbsp;Anonymous</td></tr>

   </table>
   <div class="clear"></div>
  </div>
 </fieldset>
</div>

<div class="content-container">
 <fieldset><h4>More Information:</h4>
  This error means that the request sent to the Web server contained an HTTP verb that is not allowed by the 
configured module handler for the request.
  <p><a href="https://go.microsoft.com/fwlink/?LinkID=62293&amp;IIS70Error=405,0,0x80070001,19044">View more 
information &raquo;</a></p>

 </fieldset>
</div>
</div>
</body>
</html>

However, switching to GET shows this instead:

<!--
body {
        color:#000000;
        background-color:#0072C6;
        margin:0;
}

#container {
        margin-left:auto;
        margin-right:auto;
        text-align:center;
        }

a img {
        border:none;
}

-->
</style>
</head>
<body>
<div id="container">
<a href="http://go.microsoft.com/fwlink/?linkid=66138&amp;clcid=0x409"><img src="iisstart.png" alt="IIS" width="960" height="600" /></a>
</div>
</body>
</html>
0

1 Answer 1

2

The problem was the fact that I was using the http module, rather than https. Since its protocol is https, I have to use the https module

const https = require("https")
const data = `site=meta&access_token=my_access_token&key=app_key&body=${encodeURI("Testing comment with enough length")}&preview=false`
let req = https.request({
    method: "POST",
    hostname: `api.stackexchange.com`,
    path: "/2.3/posts/51812/comments/add",
    port: 443
    headers: {
        "Content-Type": "application/x-www-form-urlencoded"
    }
}, res => {
    console.log(`code: ${res.statusCode}`) // "code: 200" and comment posted
    res.on("error", console.error)
})
req.write(data)
req.end()
6
  • 1
    Thanks for finding the solution, and reminding me why I don't like node.js - I mean why on Earth would you use different clients for HTTP and HTTPS ... I'll cleanup the comments under the question since they don't serve any purpose.
    – Glorfindel
    Feb 2 at 17:36
  • @Glorfindel I think this is a bit unfair to Node.js to consider importing the wrong core package for the job to be a flaw on the part of the runtime - HTTPS is HTTP over TLS, which is an extension of the protocol, so it makes sense to provide both HTTP and HTTPS clients in case the former is required by the end-user. Feb 3 at 20:12
  • @OlegValter OK, let me phrase my criticism differently. If the HTTP client doesn't support HTTPS, why doesn't it throw an exception with a meaningful error message? (OTOH, we should probably have this discussion in a chatroom ...)
    – Glorfindel
    Feb 3 at 20:54
  • @Glorfindel I think sending back 418 would perfectly represent requesting an HTTPS-only server via HTTP :) I am not sure why would the module throw an exception, though, as it is low-level (which is explicitly documented), and it is the onus of the server to return an appropriate HTTP status code and message when a client makes a request. The module does its job well: the client gets back a 405 response. A better question is why this one? And now I am also curious about what is the content of the Allow header sent back as it must be set when returning a 405 response. Feb 3 at 21:15
  • That said, I am not sure what status code should be sent by the API to express the "please use HTTPS" requirement - 429 does not seem to cut it as it is mostly reserved to WebSocket and HTTP/1.1 to HTTP/2 upgrades and 505 is basically the same thing. I guess sending a Upgrade-Insecure-Requests header with a request is an option, but that is on the end-user to supply too. Feb 3 at 21:21
  • always happy to drop by to a room to have a duel to the death on the merits of Node.js, though, to avoid cluttering the comment section :) Feb 3 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .