Hacker Newsnew | past | comments | ask | show | jobs | submit | halter73's commentslogin

There's a link at the top of the README to https://0x00eb.itch.io/tux-racer where you can play it without needing to host it yourself.


I'm not sure this is old enough, but could you be referencing https://neal.fun/infinite-craft/ from https://news.ycombinator.com/item?id=39205020?


Thanks, no it wasn't that, it was a basic HTML form.


> Each request will hit a new random worker, but your response is supposed to go on some other long-running SSE stream.

It seems your knowledge is a little out of date. The big difference between the older SSE transport and the new "Streamable HTTP" transport is that the JSON-RPC response is supposed to be in the HTTP response body for the POST request containing the JSON-RPC request, not "some other long-running SSE stream". The response to the POST can be a text/event-stream if you want to send things like progress notifications before the final JSON-RPC response, or it can be a plain application/json response with a single JSON-RPC response message.

If you search the web for "MCP Streamable HTTP Lambda", you'll find plenty of working examples. I'm a little sympathetic to the argument that MCP is currently underspecified in some ways. For example, the spec doesn't currently mandate that the server MUST include the JSON-RPC response directly in the HTTP response body to the initiating POST request. Instead, it's something the spec says the server SHOULD do.

Currently, for my client-side Streamable implementation in the MCP C# SDK, we consider it an error if the response body ends without a JSON-RPC response we're expecting, and we haven't gotten complaints yet, but it's still very early. For now, it seems better to raise what's likely to be an error rather than wait for a timeout. However, we might change the behavior if and when we add resumability/redelivery support.

I think a lot of people in the comments are complaining about the Streamable HTTP transport without reading it [1]. I'm not saying it's perfect. It's still undergoing active development. Just on the Streamable HTTP front, we've removed batching support [2], because it added a fair amount of additional complexity without much additional value, and I'm sure we'll make plenty more changes. As someone who's implemented a production HTTP/1, HTTP/2 and HTTP/3 server that implements [3], and also helped implement automatic OpenAPI Document generation [4], no protocol is perfect. The HTTP spec misspells "referrer" and it has a race condition when a client tries to send a request over an idle "keep-alive" connection at the same time the server tries to close it. The HTTP/2 spec lets the client just open and RST streams without the server having any way to apply backpressure on new requests. I don't have big complaints about HTTP/3 yet (and I'm sure part of that is a lot of the complexity in HTTP/2 was properly handled by the transport layer which for Kestrel means msquic), but give it more time and usage and I'm sure I'll have some. That's okay though, real artists ship.

1: https://modelcontextprotocol.io/specification/2025-03-26/bas...

2: https://github.com/modelcontextprotocol/modelcontextprotocol...

3: https://learn.microsoft.com/aspnet/core/fundamentals/servers...

4: https://learn.microsoft.com/aspnet/core/fundamentals/openapi...


Client is allowed to start a new request providing sessionid which should maintain the state from previous request.

Where do you store this state?


That github issue is closed because it's been mostly completed. As of https://github.com/modelcontextprotocol/modelcontextprotocol..., the latest draft specification does not require the resource server to act as or poxy to the IdP. It just hasn't made its way to a ratified spec yet, but SDKs are already implementing the draft.


It really depends on if you're dealing with an async stream or a single async result as the input to the next function. If a is an access token needed to access resource b, you cannot access a and b at the same time. You have to serialize your operations.


It probably depends on your lists. My uBlock Origin config had a global CSS rule blocking any elements with a #mc_embed_signup id.


Can you provide a citation for this? I’ve read older RFCs that "recommend" recipients allow single LFs to terminate headers for robustness. I’ve also read newer RFCs that weaken that recommendation and merely say the recipient "MAY" allow single LFs. I’ve never noticed an HTTP RFC say you can send headers without the full CRLF sequence, but maybe I missed something.

https://datatracker.ietf.org/doc/html/rfc2616#section-19.3 https://datatracker.ietf.org/doc/html/rfc9112#section-2.2


> I'm hoping this is satire.

Me too. It's one thing to accept single LFs in protocols that expect CRLF, but sending single LFs is a bridge to far in my opinion. I'm really surprised most of the other replies to your comment currently seem to unironically support not complying with well-established protocol specifications under the misguided notion that it will somehow make things "simpler" or "easier" for developers.

I work on Kestrel which is an HTTP server for ASP.NET Core. Kestrel didn't support LF without a CR in HTTP/1.1 request headers until .NET 7 [1]. Thankfully, I'm unaware of any widely used HTTP client that even supports sending HTTP/1.1 requests without CRLF header endings, but we did eventually get reports of custom clients that used only LFs to terminate headers.

I admit that we should have recognized a single LF as a line terminator instead of just CRLF from the beginning like the spec suggests, but people using just LF instead of CRLF in their custom clients certainly did not make things any simpler or easier for me as an HTTP server developer. Initially, we wanted to be as strict as possible when parsing request headers to avoid possible HTTP request smuggling attacks. I don't think allowing LF termination really allows for smuggling, but it is something we had to consider.

I do not support even adding the option to terminate HTTP/1.1 request/response headers with single LFs in HttpClient/Kestrel. That's just asking for problems because it's so uncommon. There are clients and servers out there that will reject headers with single LFs while they all support CRLF. And if HTTP/1.1 is still being used in 2050 (which seems like a safe bet), I guarantee most clients and servers will still use CRLF header endings. Having multiple ways to represent the exact same thing does not make a protocol simpler or easier.

[1]: https://github.com/dotnet/aspnetcore/pull/43202


LF only? Huh.

In its original terms for printing terminals, carriage return might be ambiguous. It could means either "just send the print head to column zero" or "print head to 0 and advance the line by one". The latter is what typewriters do for the Return key.

But LF always meant Line Feed, moving the paper but not the print head.

These are of course wildly out of date concepts. But it still strikes me as odd to see a Line Feed as a context reset.


>The latter is what typewriters do for the Return key.

Minor correction: mechanical typewriters do not have a Return key, but they have both operations (line feed, as well as carriage return).

The carriage return lever is typically rigged to also do line feed at the same time, by a preset amount of lines (which can be set to 0), or you can push the carriage without engaging line feed.

Technically, the lever would do LF, and pushing on it further would do CR (tensioning the carriage spring).

It is, however, true that most of the time, the users would simply push the lever until it stops without thinking about it, producing CRLF operation —

— and that CR without LF was comparatively rare.

From a pure protocol UX perspective, it would make sense IMO to have a single command for (CR + LF) too, just like the typewriter effectively does it (push the lever here to do both at once).

It seems weird that the protocol is more limited than the mechanical device that it drives, but then again, designers probably weren't involved in deciding on terminal protocol specs.


On manual typewriters there is a lever that turns the roller to accomplish a line feed (or two if set for double space.) This lever is usually located on the left side of the carriage to make it convenient to push it back to the right side in the same motion.


Isn't this what I said?

>the lever would do LF, and pushing on it further would do CR (tensioning the carriage spring).

In any case, carriage return is just as important function of the lever as line feed:

- you can also directly do line feed by turning the roller

- line feed, by itself, doesn't need a large lever

- carriage return, by itself, doesn't need a large lever either - you can simply push the carriage

- however, having a large lever is an ergonomic feature which allows you to:

1) return the carriage without moving your hands too far from the keyboard

2) do CRLF in one motion without it feeling like two things

3) If needs be, do a line feed by itself, since the force required for that is much smaller compared to the one to move the carriage (lever advantage!).

The long lever makes it so that line feed happens before carriage return. If the lever were short, you'd be able to move the carriage until it stops, and only then would the paper move up.

So I wondered why the control codes are doing the operations in the opposite order from the typewriter.

Turns out, the reasons are mechanical[1]:

>The separation of newline into two functions concealed the fact that the print head could not return from the far right to the beginning of the next line in time to print the next character. Any character printed after a CR would often print as a smudge in the middle of the page while the print head was still moving the carriage back to the first position. "The solution was to make the newline two characters: CR to move the carriage to column one, and LF to move the paper up.

Aha! Makes sense.

In a way, this was creating a de-facto protocol by usage, in a similar spirit the the author is suggesting to get rid of it.

As in: the existing standard wasn't really supported, but letting the commands go through nevertheless and allowing things to break incentivized people to collectively stick to the way of doing things that didn't result in misprints.

____ [1] https://en.wikipedia.org/wiki/Newline


Naked CR is an almost (baring legacy Mac OS) universally supported cross-platform way to print progress bars on CRT terminals.


Note that I said that it would make sense a CRLF command too, as in: in addition to separate CR and LF commands, which are useful in their own rights.

I also strongly disagree with the author that LF is useless.

So many times in code I need to type:

    Function blah(parameter1 = default1, 
                  parameter2, ...)

It would be super nice to move down from the beginning of the word "parameter1" down to the next line even when it's empty to start typing at that position.

Sure, there is auto format. But not in this comment box.

And what I'm talking about is exactly what LF was meant to do!

I want all my text boxes to support that, and to have a special key on my keyboard to do it.

Eh.


They didn't say "mechanical typewriters", just "typewriters". Electric typewriters did have a Return key that did work the way they described.


Indeed, I was clarifying that:

1) "Typewriters" in parent's comment didn't refer to mechanical typewriters, but

2) Line feed/carriage return semantics, as well as the UX of combining them into one action to proceed to the next line of text, predate electric typewriters and were effectively the same on mechanical ones.

As I wrote in the other comment, the subtle difference in semantics comes from teletypes, which couldn't advance the paper feed and return the carriage fast enough to print the next character in the timespan of one command.

Not that it applied to all teletypes, but it was the case for a very popular unit.

The makers of that machine deliberately didn't include a single command that would do CR/LF so that there'd be no way for the users to notice that.

The ordering, CR then LF, differs from the one on mechanical typewriters, where LF always precedes CR when you use the big lever, allowing one to use the same lever to produce blank lines without moving the carriage (in effect, doing LF LF LF ... LF CR).

On the teletypes though, CR LF ordering was, in any case, a lie, since in actuality, LF was happening somewhere in the middle of the carriage return, which took the time span of two commands.

The CR command had to precede LF on the teletype because it took longer, but since the mechanisms were independent, they could be executed at the same time.

This is the difference from mechanical typewriters.

Typing mechanism was also independent of CR and LF, and running CR + [type character] at the same time was bad. But having fixed-time-per-command simplified everything, so instead of waiting (..which means buffering - with potential overflow issues - or a protocol to tell the sending party to wait, which is a lot more complex), hacks like this were put in place.

My IBM selectric is not functional (got it as a repair project, didn't get to do it yet), so I can't verify, but I'd guess it doesn't need to do CR then LF, since it can simply not process input while the carriage is returning. It's OK for it to do CR and LF in any order, or simultaneously.

If the operator presses and releases a button during this time, the machine can simply do nothing; the operator will re-type the character the next instant, using the buffer in their head where the text ultimately comes from.

The teletypes didn't have that luxury, as the operator on the other end could be a computer, which was told it could send output at a certain rate, and by golly it did. Not processing a command would mean dropping data.

All that is to say that CR and LF are present on both typewriters and teletypes, with the following differences:

* mechanical typewriters always do LFCR due the mechanics of the carriage return lever, which was designed for a human operator;

* teletypes do CRLF because that's how they cope with the typist being a machine that can't be told to wait a bit until the carriage returns;

* and electric typewriters are somewhere in betwen and could do whatever, because the CR lever was replaced by the motor (like on a teletype), but the operator was still a human that could wait half a second without forgetting what it is that they wanted to type.

IMO, it's worth keeping CRLF around simply because it's a part of computer and technology history that spans nearly two centuries, from typewriters to Google docs.


> Our browsers could have been exploiting things behind NAT this entire time. Smart TVs, Smart watches, phones, anything pingable on your LAN.

Maybe if they’re running an HTTP server (which isn’t too uncommon for IoT devices) while allowing the attacker website via CORS (less likely). An IoT device listening for WebSocket or WebRTC connections won’t benefit from CORS, but those are relatively rare and ought to have other mitigations in place.

All your links show is the ability to scan ports, not even read the responses to the fetch() requests made to local IP addresses. That could be useful to an attacker, but a far cry from exploiting any smart device or having the ability to send “outgoing crafted packets” from the browser. You cannot even open arbitrary sockets or craft arbitrary HTTP requests.


> The fact that most programming languages don’t give enough semantic information for their compiler to do a good job doesn’t mean it necessary has to be so. Functional programmers just trust that their compiler will properly optimize their code.

While everyone has to trust their compiler will make reasonable optimizations to some extent, there becomes a certain point of complexity where it becomes difficult to intuitively know if a "sufficiently smart compiler"[1] will properly optimize which is problematic.

I realize you're arguing Haskell is worse than Ocaml in this regard, but I'd argue it's harder to reason about how functional code will be translated into machine code than comparable procedural code in general.

[1]: https://prog21.dadgum.com/40.html


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: