-
Content Count
2322 -
Joined
-
Last visited
-
Days Won
94
Everything posted by Remy Lebeau
-
It has the public Receive() method inherited from TIdStack, but that takes only a socket handle and a TIdBytes as parameters. I assume you want access to the flags parameter of recv()? For that, you can use the protected TIdStackBSDBase.WSRecv() method. type TIdStackBSDBaseAccess = class(TIdStackBSDBase) end; TIdStackBSDBaseAccess(GBSDStack).WSRecv(AContext.Binding.Handle, buffer, length, MSG_PEEK);
-
https://github.com/IndySockets/Indy/issues/410
-
Indy's TIdSocketHandle class does not have a SetSockOpt() overload for non-integer inputs, but its TIdStackBSDBase class does (for BSD-based socket stacks, like Linux and Windows): uses ..., IdStackBSDBase; GBSDStack.SetSocketOption(AContext.Binding.Handle, Id_SOL_SOCKET, Id_SO_RCVTIMEO, mTime, SizeOf(TTimeVal)); I probably need to update Indy to expose this overload in TIdSocketHandle and TIdStack for easier use.
-
That's good to hear (not that you are tired, but that you got it working). FYI, if the mapped host/port is wrong and the connection can't be established, the TIdMappedPortTCP's OnException event will be triggered. On a side note: the way you are using TThread.Queue() is a potential crash waiting to happen. TThread.Queue() is asynchronous, and your anonymous procedures are capturing the local TIdContext variable, which points to an object that may or may not be valid anymore if the client disconnects before the Queue request is processed by the main thread. Instead, you should first save the desired values locally and then capture those variables instead, eg: procedure TMyClass.OnServerConnect(AContext: TIdContext); var lPeerIP: string; lPort: TIdPort; begin lPeerIP := AContext.Binding.PeerIP; lPort := AContext.Binding.Port; TThread.Queue(nil, procedure begin WriteLn('OnConnect from ' + lPeerIP + ' to ' + lPort.ToString); end ); end; procedure TMyClass.OnServerExecute(AContext: TIdContext); var lPeerIP: string; lPort: TIdPort; begin lPeerIP := AContext.Binding.PeerIP; lPort := AContext.Binding.Port; TThread.Queue(nil, procedure begin WriteLn('OnExecute from ' + lPeerIP + ' to ' + lPort.ToString); end ); end;
-
Multipart/form-data vs x-www-form-urlencoded (Indy HTTP server)
Remy Lebeau replied to Joe Sansalone's topic in Network, Cloud and Web
That will only work if the email is entirely textual, no binary attachments. And also, only if the sender actually sends the text data as UTF-8, which is not a guarantee. Try this instead: var MsgEnd: Boolean; Decoder, NewDecoder: TIdMessageDecoder; Line, Boundary, BoundaryStart, BoundaryEnd: String; Dest: TStream; begin ... Boundary := ExtractHeaderSubItem(ARequestInfo.ContentType, 'boundary', QuoteHTTP); BoundaryStart := '--' + Boundary; BoundaryEnd := BoundaryStart + '--'; repeat Line := ReadLnFromStream(ARequestInfo.PostStream, -1, True); if Line = BoundaryEnd then Exit; until Line = BoundaryStart; Decoder := TIdMessageDecoderMIME.Create(nil); try MsgEnd := False; repeat TIdMessageDecoderMIME(Decoder).MIMEBoundary := Boundary; Decoder.SourceStream := ARequestInfo.PostStream; Decoder.FreeSourceStream := False; Decoder.ReadHeader; case Decoder.PartType of mcptText, mcptAttachment: begin Dest := TMemoryStream.Create; try NewDecoder := Decoder.ReadBody(Dest, MsgEnd); try // use Dest as needed... finally Decoder.Free; Decoder := NewDecoder; end; finally Dest.Free; end; end; mcptIgnore: begin FreeAndNil(Decoder); Decoder := TIdMessageDecoderMIME.Create(nil); end; mcptEOF: begin MsgEnd := True; end; end; until (Decoder = nil) or MsgEnd; finally Decoder.Free; end; end; What you SHOULD be doing is actually parsing the MIME data according to the official MIME RFC specifications. -
[Question/Feature] SSL/TLS fallback using magic bytes
Remy Lebeau replied to FearDC's topic in ICS - Internet Component Suite
That is the basic jist of it, yes. Though, detecting a viable handshake is slightly more complex than just testing the first 2 bytes. I did write some code for this a long time ago, I'll have to look for it. -
Multipart/form-data vs x-www-form-urlencoded (Indy HTTP server)
Remy Lebeau replied to Joe Sansalone's topic in Network, Cloud and Web
That depends on how you are parsing it. TIdHTTPServer does not parse 'multipart/form-data' for you (that is on the todo list), so you have to parse the raw data yourself. What does your code look like for that? You can use Indy's TIdMessageDecoderMIME class to help you parse 'multipart/form-data' from the ARequestInfo.PostStream data. -
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
Yup 😢 -
IOHandler.Write() problems with SocketError # 10053 exception
Remy Lebeau replied to SneakyPeaky99's topic in Indy
First, that is a lot of code to go through, and blue text on black a background is very difficult to read. Second, there is no mention of this failing AddStr() method being called anywhere in those screenshots. -
Collect JSON ajax data from a local zigbee web server
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
There are countless examples of that online all over the place. Start with the TThread class, overriding its virtual Execute() method, and use its Synchronize() or Queue() method when you need to communicate with the main UI thread. Seems like you already know how to do that. So, what's stopping you from using that? That would be a perfectly valid approach. And? It still works. All that means is that code which touches VCL controls needs to run in the context of the main UI thread. There are many different way to do that. One way is TThread::Synchronize()/TThread::Queue(). Another way is using window messages (for example, wParam and lParam can hold pointers to data). Another way is using a thread-safe container and having the main thread poll it periodically, such as in a timer. Or any combination of these approaches (for example, putting data in a thread-safe container, then posting a message to poll the container). Are you planning on writing portable code in C++Builder only, or do you need to support other C++ compilers? If you stick with just C++Builder then there is no reason not to use what it provides, like TThread (which does run on all supported platforms). But, if you want to support other compilers, then you have to stick with only the standard C++ library and 3rd party cross-platform libraries. Those headers were introduced in C++11. Are you using one of the clang-enhanced C++ compilers that support C++11? The "classic" Borland compiler only supports a small subset of C++11 language features, but no C++ standard library features. So make sure you are using a compiler that supports what you want.- 10 replies
-
- c++ builder 11
- json
-
(and 4 more)
Tagged with:
-
TIdHTTP->Get UnicodeString trouble
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
This issue has nothing to do with Unicode. You simply have a logic bug in your code. You are already doing it. You just have a mistake in your format string. BTW, you can get rid of the char[] array and use the (s)printf() method of AnsiString/UnicodeString instead, eg: AnsiString url; url.printf("http://%s/ajax.xml", ethTcp_ip); String us = IdHTTP1->Get(url); out << "Response" << endl << AnsiString(us).c_str() << endl; Memo1->Lines->Text = us; Another option, albeit a little heavier-handed, is to use Indy's TIdURI class, eg: #include <IdURI.hpp> #include <memory> std::unique_ptr<TIdURI> idUri(new TIdURI); // or: auto idUri = std::make_unique<TIdURI>(); idUri->Protocol = _D("http"); idUri->Host = ethTcp_ip; idUri->Path = _D("/"); idUri->Document = _D("ajax.xml"); String url = idUri->URI; Look VERY CAREFULLY at the two URLs you are passing to TIdHTTP::Get(). What do you see that is different between them? In the bad example, there is an extra erroneous '/' character in front of the filename: good: "http://192.168.1.123/ajax.xml" bad: "http://192.168.1.123//ajax.xml" ^ Fix your format string to remove the erroneous '/' character. https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/ https://blogs.embarcadero.com/we-are-experiencing-a-hardware-outage/ https://ideasawakened.com/post/embarcadero-network-issues Yes, but you are not experiencing a Unicode problem, since your URL contains only ASCII characters. https://github.com/IndySockets/Indy/wiki/Documentation -
[Question/Feature] SSL/TLS fallback using magic bytes
Remy Lebeau replied to FearDC's topic in ICS - Internet Component Suite
If you want to do this TLS handshake detection in TIdMappedPortTCP, the best place to handle this is in the OnBeforeConnect event, which is fired immediately after a new client is accepted by TIdMappedPortTCP and before its associated OutboundClient is connected to the next server. The OnExecute event is fired after the OutboundClient is connected to the next server and the accepted client has sent data which has been read into its InputBuffer. By then, its too late for the TLS detection since the connection is already receiving application data after the TLS session is established. No, you do not. You can't "undo" a socket read. Nor will doing so help you with detecting the TLS handshake, anyway. You have to peek the bytes directly from the socket itself, not from the InputBuffer that is on top of the socket. -
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
-
Why are access violations not shown in popups with EurekaLog ?
Remy Lebeau replied to dormky's topic in General Help
Then there IS a try..except involved, but its inside the VCL framework wrapping the call to the event handler (and most other events, for that matter). That is why, for example, if you raise an exception inside an OnClick event and don't catch it yourself, you will still see a default popup message appear. There is a default try..except inside the framework for handling UI errors. -
I was just thinking the same thing! So many QC tickets were lost, and not linked/duplicated into QP tickets.
-
Delphi 12 requires missing DLL on Server 2008
Remy Lebeau replied to Tsagoth's topic in RTL and Delphi Object Pascal
Delphi 12 does not support Server 2008 or 2008 R2 as a deployment platform. The minimum supported Server version is 2019. Because Window 7 (SP1+) is a supported deployment platform. See: https://docwiki.embarcadero.com/RADStudio/Athens/en/Supported_Target_Platforms -
Access violation when creating thread
Remy Lebeau replied to ErikT's topic in Algorithms, Data Structures and Class Design
On a side note, you should not be passing an Owner to your thread. You are creating the TPing object inside your worker thread, so don't assign a component from the main thread as its Owner. Set the Owner to nil instead, and then Free() the object when you are done using it. -
Unfortunately, that does not work. The LastError property is set only if THandleObject.Wait() fails with an OS error. If a creation or acquisition/release fails, an exception is raised instead. If a creation succeeds with a non-zero error code, the LastError property is not set to reflect that. I have now opened a ticket for that feature: RSP-44312: THandleObject.LastError should be set during object creation
-
Collect JSON ajax data from a local zigbee web server
Remy Lebeau replied to dan27125's topic in Network, Cloud and Web
@dan27125 I commented earlier on your same question on StackOverflow: https://stackoverflow.com/questions/77868076/collect-json-ajax-data-from-a-local-zigbee-web-server Now that I see this post, the StackOverflow post appears to be a direct copy/paste of this post? That would explain why it mentions "Attached is ajax.xml, debug.html" without actually providing those files. It is generally frowned upon by internet etiquette to post the same question in multiple forums at the same time. It shows a lack of patience on your part, and a disrespect for people who might take time out of their day to answer. That being said, now that I see the relevant data files are on this post and not the StackOverflow post, I can fill in some gaps from my StackOverflow comment. The HTML is running a client-side JavaScript that uses a timer to invoke the browser's built-in AJAX client at regular intervals to send an HTTP request to download the XML file, parse the XML, and inject the results into the HTML elements using the browser's DOM. There is no streaming involved at all, each data update is an independent HTTP request. In C++Builder, you would simply do the same thing. Run a timer that uses any HTTP client you want (TIdHTTP, T(Net)HTTPClient, libcurl, etc) to download the XML from the appropriate URL, and then you can use any XML library, such as (T|I)XMLDocument, to parse the XML and do what you need with the data values.- 10 replies
-
- c++ builder 11
- json
-
(and 4 more)
Tagged with:
-
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
It is "up", but it is not entirely stable. I was just using it a few minutes ago and still got a few errors on it. But yes, I could access pages. -
FYI - Several Embarcadero services are currently unavailable
Remy Lebeau replied to Keesver's topic in General Help
The parent list (https://stats.uptimerobot.com/3yP3quwNW) doesn't appear to include any GetIt servers for monitoring. Unless maybe they are listed under a different name (Downloads, perhaps?) -
In the short term, yes. But on the other hand, external links tend to break over time, which makes discussions harder to follow for future readers who may be looking for solutions to similar problems, if they can't see the code that is being discussed.
- 8 replies
-
- tidtcpserver
- openssl
-
(and 1 more)
Tagged with:
-
Error on loading data from the server getit-104.embarcadero.com
Remy Lebeau replied to Didier Cabalé's topic in Delphi IDE and APIs
Did you read the discussion I linked to earlier? You would have to modify the Registry directly. However... At the moment, not the online version, no. Several key systems, including GetIt, are completely down (and have been for over a week now!) due to a hardware outage: https://blogs.embarcadero.com/we-are-experiencing-a-hardware-outage/ If you really need access to GetIt right now, the best you could do is put GetIt into offline mode and let it work with its local cache/ISO, including any local packages you install into it manually. -
IOHandler.Write() problems with SocketError # 10053 exception
Remy Lebeau replied to SneakyPeaky99's topic in Indy
You appear to be using TIdHTTPServer, so why are you using IOHandler.Write() directly at all? You should be using ResponseInfo.ContentText or ResponseInfo.ContentStream instead. Unless you are streaming data that is dynamically generated in chunks while the response is still being written to the client? That is not a common thing to do for HTML. Can you please show a more complete example of how exactly this AddStr() method is being used in relation to your server? How are you configuring the ResponseInfo before calling AddStr() the 1st time? Without more info, my guess is that you are probably violating the HTTP protocol in some way and the error is just a side effect. The error simply means the connection has been dropped on the server side, but that could happen for any number of reasons not directly related to your code. -
That sounds more like a server-side issue, if it affects both components. Did you check if the requests are different in any way between Delphi 11 vs 12?